The history of luaTEX 2006–2009 / v 0.50 - Pragma ADE
The history of luaTEX 2006–2009 / v 0.50 - Pragma ADE The history of luaTEX 2006–2009 / v 0.50 - Pragma ADE
normalizers characters words fonts lists after cleanup and preparation handlers operations on individual characters operations on words font related manipulations manipulations on the list as a whole experimental (or module) plugins Here ‘plugins’ are experimental handlers or specialized ones provided in modules that are not part of the kernel. The categories are not that distinctive and only provide a convenient way to group actions. Examples of normalizers are: checking for missing characters and replacing character references by fallbacks. Character processors are for instance directional analysers (for right to left typesetting), case swapping, and specialized character triggered hyphenation (like compound words). Word processors deal with hyphenation (here we use the default function provided by LuaTEX) and spell checking. The font processors deal with Open- Type as well as the ligature building and kerning of other font types. Finally, the list processors are responsible for tasks like special spacing (french punctuation) and kerning (additional inter--character kerning). Of course, this all is rather ConTEXt specic and we expect to add quite some more less trivial handlers the upcoming years. Many of these handlers are triggered by attributes. Nodes can have many attributes and each can have many values. Traditionally TEX had only a few attributes: language and font, where the rst is not even a real attribute and the second is only bound to glyph nodes. In LuaTEX language is also a glyph property. The nice thing about attributes is that they can be set at the TEX end and obey grouping. This makes them for instance perfect for implementing color mechanims. Because attributes are part of the nodes, and not nodes themselves, they don't inuence or interfere processing unless one explicitly tests for them and acts accordingly. In addition to the mentioned task ‘processors’ we also have a task ‘shipouts’ and there will be more tasks in future versions of ConTEXt. Again we have subcategories, currently: subcategory before normalizers nishers after intended usage experimental (or module) plugins cleanup and preparation handlers manipulations on the list as a whole experimental (or module) plugins An example of a normalizer is cleanup of the ‘to be shipped out’ list. Finishers deal with color, transparency, overprint, negated content (sometimes used in page imposition), special effects effect (like outline fonts) and viewer layers (something pdf). Quite possible hyperlink support will also be handled there but not before the backend code is rewritten. 272 The order of things
The previous description is far from complete. For instance, not all handlers use the same interface: some work head onwards, some need a tail pointer too. Some report back success or failure. So the task handler needs to normalize their usage. Also, some effort goes into optimizing the task in such a way that processing the document is still reasonable fast. Keep in mind that each construction of a box invokes a callback, and there are many boxes used for constructing a page. Even a nilled callback is one, so for a simple one word paragraph four callbacks are triggered: the (nilled) hyphenate, ligature and kern callbacks as well as the one called pre_linebreak_filter. The task handler that we plug in the lter callbacks calls many functions and each of them does one of more passes over the node list, and in turn might do many call to functions. You can imagine that we're quite happy that TEX as well as Lua is so efcient. As I already mentioned, implementing a task handler as well as deciding what actions within tasks to perform in what order is specic for the way a macro package is set up. The following code can serve as a starting point filters = { } -- global namespace local list = { } function filters.add(fnc,n) if not n or n > #list + 1 then table.insert(list,#list+1) elseif n < 0 then table.insert(list,1) else table.insert(list,n) end end function filters.remove(fnc,n) if n and n > 0 and n
- Page 226 and 227: In LuaTEX with ConTEXt MkIV support
- Page 228 and 229: • Designers (or programmers) may
- Page 230 and 231: 228 OpenType: too open?
- Page 232 and 233: cannot be grabbed and they make the
- Page 234 and 235: 232 It works!
- Page 236 and 237: when writing the result to le, TEX
- Page 238 and 239: 236 Virtual Reality
- Page 240 and 241: \start \textdir TLT one \bidilro tw
- Page 242 and 243: 240 Getting lost
- Page 244 and 245: using a few arabic fonts, some chin
- Page 246 and 247: The core data structure that we nee
- Page 248 and 249: table can contain information about
- Page 250 and 251: The ConTEXt cross reference mechani
- Page 252 and 253: of them. Each lookup has a detailed
- Page 254 and 255: otf.replacements otf.sequences otf.
- Page 256 and 257: features: analyze=yes, calt=yes, cc
- Page 258 and 259: feature mark, lookup ml_arab_l_16_s
- Page 260 and 261: للِ ه ِ feature init, lo
- Page 262 and 263: features: analyze=yes, calt=yes, cc
- Page 264 and 265: esult: 1: [+TRT] U+6DD: [-TRT]
- Page 266 and 267: 2: [+TRT] U+F01DD: [-TRT] The
- Page 268 and 269: Pro. Dr. Donld E. Knuth feature cal
- Page 270 and 271: 268 Tracking
- Page 272 and 273: The order in which this happens now
- Page 276 and 277: local function hyphenation(head,tai
- Page 278 and 279: 276 The order of things
- Page 280 and 281: of LuaTEX Taco and I worked in para
- Page 282 and 283: Next we see (scaled) Latin Modern:
- Page 284 and 285: As you can see, it is possible to a
- Page 286 and 287: next: U+FF008 { => U+FF06E { => U+F
- Page 288 and 289: end } commands = { { "slot", 1, bas
- Page 290 and 291: (a,b) = (1.20,3.40) So we don't nee
- Page 292 and 293: } description = "SOLIDUS", directio
- Page 294 and 295: ⎧ ⎪ ⎪ ⎪ ⎨ ⎪ ⎪ ⎪ ⎩
- Page 296 and 297: 840 italic 60 top_accent (0,1020) f
- Page 298 and 299: 296 Unicode math
- Page 300 and 301: tex.print("access") else tex.print(
- Page 302 and 303: 300 User code
- Page 304 and 305: namespace with code not coming from
- Page 306 and 307: • The code denes a few global tab
- Page 308 and 309: ut this now refers to an index in a
- Page 310 and 311: On the agenda is xing some ‘hyphe
- Page 312 and 313: We also use the opportunity to slow
- Page 314 and 315: Math. Because the TEX Gyre math pro
- Page 316 and 317: Tracing on Taco's machine has shown
- Page 318 and 319: node list callback tasks - 4 unique
- Page 320 and 321: pdftex 1.28 (23) 2.07 (144) 6.96 (2
- Page 322 and 323: July 19, 2009 - The number of files
<strong>The</strong> previous description is far from complete. For instance, not all handlers use the same<br />
interface: some work head onwards, some need a tail pointer too. Some report back<br />
success or failure. So the task handler needs to normalize their usage. Also, some effort<br />
goes into optimizing the task in such a way that processing the document is still reasonable<br />
fast. Keep in mind that each construction <strong>of</strong> a box invokes a callback, and there<br />
are many boxes used for constructing a page. Even a nilled callback is one, so for a simple<br />
one word paragraph four callbacks are triggered: the (nilled) hyphenate, ligature and<br />
kern callbacks as well as the one called pre_linebreak_filter. <strong>The</strong> task handler that<br />
we plug in the lter callbacks calls many functions and each <strong>of</strong> them does one <strong>of</strong> more<br />
passes over the node list, and in turn might do many call to functions. You can imagine<br />
that we're quite happy that TEX as well as Lua is so efcient.<br />
As I already mentioned, implementing a task handler as well as deciding what actions<br />
within tasks to perform in what order is specic for the way a macro package is set up.<br />
<strong>The</strong> following code can serve as a starting point<br />
filters = { } -- global namespace<br />
local list = { }<br />
function filters.add(fnc,n)<br />
if not n or n > #list + 1 then<br />
table.insert(list,#list+1)<br />
elseif n < 0 then<br />
table.insert(list,1)<br />
else<br />
table.insert(list,n)<br />
end<br />
end<br />
function filters.remove(fnc,n)<br />
if n and n > 0 and n