{"id":1496,"date":"2011-11-18T12:03:03","date_gmt":"2011-11-18T12:03:03","guid":{"rendered":"http:\/\/www.readytext.co.uk\/?p=1496"},"modified":"2013-11-28T09:03:14","modified_gmt":"2013-11-28T09:03:14","slug":"trivial-example-of-luatexs-post_linebreak_filter","status":"publish","type":"post","link":"https:\/\/www.readytext.co.uk\/?p=1496","title":{"rendered":"Trivial example of LuaTeX&#8217;s post_linebreak_filter"},"content":{"rendered":"<p>LuaTeX provides a very interesting facility called &#8220;callbacks&#8221;. A callback is a Lua function that you provide and which LuaTeX will call at certain times during the course of processing your document. LuaTeX defines a number of callback opportunities which are detailed in the LuaTeX Reference Manual. <\/p>\n<p>To use callbacks you have to provide the Lua function and then register it with LuaTeX so that it knows to call your function at the appropriate time. You can provide callbacks for many purposes such as reading input files, processing input buffers, hooking into line breaking, page building and so forth. <\/p>\n<p>Callbacks are an <em>exceptionally<\/em> powerful concept and they open the door to very sophisticated document processing solutions. For example, you can hook into the internal node lists and process them to achieve special effects. Here is a very simple and short &#8220;plain TeX&#8221; example of hooking into LuaTeX&#8217;s <code>post_linebreak_filter<\/code> (and, in addition, playing with setting the page size). <\/p>\n<p>To quote the LuaTeX Reference Manual <\/p>\n<blockquote><p><strong>post_linebreak_filter<\/strong>: This callback is called just after LuaTEX has converted a list of nodes into a stack of \\hboxes.<\/p><\/blockquote>\n<p>In the following example, just after LuaTeX has processed the vbox, and broken the paragraph into lines, it calls a Lua function called <code>linelist<\/code> which simply ships out each line in the paragraph. Also, and not part of the callback, a copy of the vbox is output on the last page, setting the page size to be that of the vbox.<\/p>\n<pre class=\"brush: plain; light: false; title: ; toolbar: true; notranslate\" title=\"\">\r\n\\pdfoutput=1\r\n\\hoffset-1in\r\n\\voffset-1in\r\n\\nopagenumbers\r\n\\directlua{\r\nlinelist=function(head)\r\nlocal boxer=200\r\nfor line in node.traverse_id('hlist',head) do\r\n           tex.setbox(boxer, node.copy(line))\r\n           tex.box&#x5B;boxer].height= tex.box&#x5B;boxer].height+65536 %add 65536sp = 1pt to avoid clipping\r\n           tex.box&#x5B;boxer].depth= tex.box&#x5B;boxer].depth+65536 %add 65536sp = 1pt to avoid clipping\r\n           tex.shipout(boxer)\r\nend\r\nreturn head\r\nend\r\ncallback.register(&quot;post_linebreak_filter&quot;,linelist)\r\n}\r\n\r\n\\setbox1000=\\vbox{\\hsize=50mm Let us examine the structure of a list of hboxes in a vbox because\r\nit is an instructive thing to do.}\r\n\\pdfpagewidth=\\wd1000\r\n\\vsize=\\ht1000\r\n\\advance\\vsize by 65536 sp\r\n\\pdfpageheight=\\vsize\r\n\\box1000\r\n\\bye\r\n<\/pre>\n<h2>The output<\/h2>\n<p>The output is a 5-page PDF: the first four pages are the individual lines in the typeset paragraph and the final page is the vbox. <\/p>\n<p><iframe src=\"http:\/\/docs.google.com\/gview?url=http:\/\/readytext.co.uk\/files\/dumpline.pdf&amp;embedded=true\" style=\"width:100%; height:400px;\" frameborder=\"0\"><\/iframe><\/p>\n","protected":false},"excerpt":{"rendered":"<p>LuaTeX provides a very interesting facility called &#8220;callbacks&#8221;. A callback is a Lua function that you provide and which LuaTeX will call at certain times during the course of processing your document. LuaTeX defines a number of callback opportunities which are detailed in the LuaTeX Reference Manual. To use callbacks you have to provide the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15,3],"tags":[],"class_list":["post-1496","post","type-post","status-publish","format-standard","hentry","category-examples","category-luatex"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/www.readytext.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/1496","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.readytext.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.readytext.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.readytext.co.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.readytext.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1496"}],"version-history":[{"count":11,"href":"https:\/\/www.readytext.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/1496\/revisions"}],"predecessor-version":[{"id":3275,"href":"https:\/\/www.readytext.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/1496\/revisions\/3275"}],"wp:attachment":[{"href":"https:\/\/www.readytext.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.readytext.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.readytext.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}