diff options
author | Karl Berry <karl@freefriends.org> | 2015-12-29 00:15:08 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2015-12-29 00:15:08 +0000 |
commit | 5460c8b6efbae612a6bed2069f92d1957234f75f (patch) | |
tree | a6b9026217840743a7f496b89381257d8eff0941 | |
parent | 68264d1e4e757388b36fe4250909b957a292436b (diff) |
chickenize (26dec15)
git-svn-id: svn://tug.org/texlive/trunk@39222 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Master/texmf-dist/doc/luatex/chickenize/README | 7 | ||||
-rw-r--r-- | Master/texmf-dist/doc/luatex/chickenize/chickenize.pdf | bin | 172855 -> 191886 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/luatex/chickenize/chickenize.dtx | 414 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/chickenize/chickenize.lua | 209 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/chickenize/chickenize.sty | 5 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/chickenize/chickenize.tex | 119 |
6 files changed, 614 insertions, 140 deletions
diff --git a/Master/texmf-dist/doc/luatex/chickenize/README b/Master/texmf-dist/doc/luatex/chickenize/README index d31156506d3..730176db8b9 100644 --- a/Master/texmf-dist/doc/luatex/chickenize/README +++ b/Master/texmf-dist/doc/luatex/chickenize/README @@ -6,13 +6,14 @@ To produce the package files, run lualatex on chickinize.dtx, wich should result chickenize.sty (LaTeX user interface) chickenize.lua (Lua package code) [does the actual work] -You need an up-to-date TeX Live (2013) to use this package. Maybe a full MiKTeX will do, too. +You need an up-to-date TeX Live (2015, possible) to use this package. Maybe a full MiKTeX will do, too. For any comments or suggestions, contact me: arno dot trautmann at gmx dot de Hope you have fun with this package! -This package is copyright © 2013 Arno L. Trautmann. It may be distributed and/or +This package is copyright © 2015 Arno L. Trautmann. It may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c -of this license or (at your option) any later version. This work has the LPPL maintenance status ‘maintained’. +of this license or (at your option) any later version. This work has the LPPL mainten- +ance status ‘author-maintained’. diff --git a/Master/texmf-dist/doc/luatex/chickenize/chickenize.pdf b/Master/texmf-dist/doc/luatex/chickenize/chickenize.pdf Binary files differindex 984bbf81f3a..3ff13d3496e 100644 --- a/Master/texmf-dist/doc/luatex/chickenize/chickenize.pdf +++ b/Master/texmf-dist/doc/luatex/chickenize/chickenize.pdf diff --git a/Master/texmf-dist/source/luatex/chickenize/chickenize.dtx b/Master/texmf-dist/source/luatex/chickenize/chickenize.dtx index e1a127811cd..d98dcb84b89 100644 --- a/Master/texmf-dist/source/luatex/chickenize/chickenize.dtx +++ b/Master/texmf-dist/source/luatex/chickenize/chickenize.dtx @@ -12,14 +12,14 @@ To produce the package files, run lualatex on chickinize.dtx, wich should result chickenize.sty (LaTeX user interface) chickenize.lua (Lua package code) [does the actual work] -You need an up-to-date TeX Live (2012, if possible, maybe 2011 will do) to use this package. Maybe a full MiKTeX will will also work. (Not tested!) +You need an up-to-date TeX Live (2015, if possible) to use this package. Maybe a full MiKTeX will will also work. (Not tested!) For any comments or suggestions, contact me: arno dot trautmann at gmx dot de Hope you have fun with this package! -This package is copyright © 2013 Arno L. Trautmann. It may be distributed and/or +This package is copyright © 2015 Arno L. Trautmann. It may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c of this license or (at your option) any later version. This work has the LPPL mainten- ance status ‘maintained’. @@ -37,7 +37,7 @@ ance status ‘maintained’. EXPERIMENTAL CODE -This package is copyright © 2013 Arno L. Trautmann. It may be distributed and/or +This package is copyright © 2015 Arno L. Trautmann. It may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c of this license or (at your option) any later version. This work has the LPPL mainten- ance status ‘maintained’. @@ -104,7 +104,8 @@ ance status ‘maintained’. } \begin{document} -{\hfill \parbox{6.3cm}{{\TGChorus{\large »\,}The Monty Pythons, were they \TeX~users,\\\hspace*{.2em} could have written the chickenize macro.{\large \textit «}}\\[1ex] +{\hspace*{-2cm}{\scalebox{.2}{\drawchicken} +\hfill\hfill \parbox{6.3cm}{{\TGChorus{\Large »\,}\large The Monty Pythons, were they \TeX~users,\\\hspace*{.2em} could have written the chickenize macro.{\Large \textit «}}\\[1ex] \hspace*{4cm}\small Paul Isambert}\kern-2.5cm } @@ -116,11 +117,13 @@ chickenize \unrainbowcolor -\centerline{v0.2.1a} -\centerline{\hspace*{2cm} Arno Trautmann} +\centerline{v0.2.2} +\centerline{\hspace*{2cm} Arno L. Trautmann \ALT} \centerline{\href{mailto:arno.trautmann@gmx.de}{arno.trautmann@gmx.de}} \kern.5cm +\textcolor{blue}{How to read this document.} + This is the documentation of the package |chickenize|. It allows manipulations of any Lua\TeX\ document\footnote{The code is based on pure Lua\TeX\ features, so don't even try to use it with any other \TeX\ flavour. The package is tested under plain Lua\TeX\ and Lua\LaTeX. If you tried using it with Con\TeX t, please share your experience, I will gladly try to make it compatible!} exploiting the possibilities offered by the callbacks that influence line breaking (and some other stuff). Most of this package's content is just for fun and educational use, but there are also some functions that can be useful in a normal document. The table on the next page shortly informs you about some of your possibilities and provides links to the (documented) Lua functions. The \TeX\ interface is presented \hyperlink{texinterface}{below}. @@ -137,7 +140,7 @@ If you have any suggestions or comments, just drop me a mail, I’ll be happy to \small\noindent \fbox{\parbox{.97\textwidth}{ -This package is copyright © 2013 Arno L. Trautmann. It may be distributed and/or +This package is copyright © 2015 Arno L. Trautmann. It may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c of this license or (at your option) any later version. This work has the LPPL maintenance status ‘maintained’.}} \vspace*{1cm} @@ -154,10 +157,11 @@ A small and incomplete overview of the functionalities offered by this package. \begin{longtabu} to .95\textwidth [c]{lX[j]} \hbox to 0cm{\bfseries \hspace*{2cm} maybe useful functions}\\ \cmidrule(lr){1-2} -\hyperref[sec:colorstretch]{colorstretch} & shows grey boxes that visualise the badness and font expansion of each line\\ +\hyperref[sec:colorstretch]{colorstretch} & shows grey boxes that visualise the badness and font expansion line-wise\\ \hyperref[sec:letterspaceadjust]{letterspaceadjust} & improves the greyness by using a small amount of letterspacing\\ \hyperref[sec:substitutewords]{substitutewords} & replaces words by other words (chosen by the user)\\ \hyperref[sec:variantjustification]{variantjustification} & Justification by using glyph variants\\ +\hyperref[sec:suppressonecharbreak]{suppressonecharbreak} & suppresses linebreaks after single-letter words\\ \addlinespace\addlinespace \hbox to 0cm{\bfseries \hspace*{2cm} less useful functions} \\ \cmidrule(lr){1-2} @@ -165,7 +169,8 @@ A small and incomplete overview of the functionalities offered by this package. \hyperref[sec:countglyphs]{countglyphs} & counts the number of glyphs in the whole document\\ \hyperref[sec:countwords]{countwords} & counts the number of words in the whole document\\ \hyperref[sec:leetspeak]{leetspeak} & translates the (latin-based) input into 1337 5p34k\\ -\hyperref[sec:randomuclc]{randomuclc} & alternates randomly between uppercase and lowercase\\ +\hyperref[sec:medievalumlaut]{medievalumlaut} & \medievalumlaut changes each umlaut to normal glyph plus “e” above it: äöü\\ +\hyperref[sec:randomuclc]{randomuclc} & \unmedievalumlaut alternates randomly between uppercase and lowercase\\ \hyperref[sec:randomrainbowcolor]{rainbowcolor} & changes the color of letters slowly according to a rainbow\\ \hyperref[sec:randomrainbowcolor]{randomcolor} & prints every letter in a random color\\ \hyperref[sec:tabularasa]{tabularasa} & removes every glyph from the output and leaves an empty document\\ @@ -204,8 +209,9 @@ The effect of the commands can be influenced, not with arguments, but only via t \begin{description} \def\command#1{\item[\ttfamily \color{blue} \textbackslash#1]} +\command{allownumberincommands} Normally, you cannot use numbers as part of a control sequence (or, command) name. This makes perfect sense and is good as it is. However, just to raise awareness to this, we provide a command here that changes the chategory codes of numbers 0–9 to 11, i.\,e.~normal character. So they \emph{can} be used in command names. However, this will break many packages, so do \emph{not} expect anything to work! At least use it \emph{after} all packages are loaded. \command{boustrophedon} Reverts every second line. This immitates archaic greek writings where one line was right-to-left, the next one left-to-right etc.\footnote{\url{en.wikipedia.org/wiki/Boustrophedon}} Interestingly, also every glyph was adaptet to the writing direction, so all glyphs are inverted in the right-to-left lines. Actually, there are two versions of this command that differ in their implementation: |\boustrophedon| rotates the whole line, while |\boustrophedonglyphs| changes the writing direction and reverses glyph-wise. The second one takes much more compilation time, but may be more reliable. A Rongorongo\footnote{\url{en.wikipedia.org/wiki/Rongorongo}} similar style boustrophedon is available with |\boustrophedoninverse| or |\rongorongonize|, where subsequent lines are rotated by 180° instead of mirrored. -\command{countglyphs} \textcolor{blue}{\texttt{\textbackslash countwords}} Counts every printed character (or word, respectively) that appeared in anything that is a paragraph. Which is quite everything, in fact, \emph{exept} math mode! The total number will be printed at the end of the log file/console output. +\command{countglyphs} \textcolor{blue}{\texttt{\textbackslash countwords}} Counts every printed character (or word, respectively) that appears in anything that is a paragraph. Which is quite everything, in fact, \emph{exept} math mode! The total number of glyphs/words will be printed at the end of the log file/console output. For glyphs, also the number of use for every letter is printed separately. \command{chickenize} Replaces every word of the input with the word “chicken”. Maybe sometime the replacement will be made configurable, but up to now, it's only chicken. To be a bit less static, about every 10\textsuperscript{th} chicken is uppercase. However, the beginning of a sentence is not recognized automatically.\footnote{If you have a nice implementation idea, I'd love to include this!} \command{colorstretch} Inspired by Paul Isambert's code, this command prints boxes instead of lines. The greyness of the first (left-hand) box corresponds to the badness of the line, i.\,e. it is a measure for how much the space between words has been extended to get proper paragraph justification. The second box on the right-hand side shows the amount of stretching/shrinking when font expansion is used. Together, the greyness of both boxes indicate how well the greyness is distributed over the typeset page. \command{dubstepize} wub wub wub wub wub BROOOOOAR WOBBBWOBBWOBB BZZZRRRRRRROOOOOOAAAAA … (inspired by \url{http://www.youtube.com/watch?v=ZFQ5EpO7iHk} and \url{http://www.youtube.com/watch?v=nGxpSsbodnw}) @@ -213,6 +219,7 @@ The effect of the commands can be influenced, not with arguments, but only via t \command{hammertime} STOP! —— Hammertime! \command{leetspeak} Translates the input into 1337 speak. If you don't understand that, lern it, n00b. \command{matrixize} Replaces every glyph by a binary representation of its ASCII value. +\command{medievalumlaut} Changes every lowercase umlaut into the corresponding vocale glyph with a small “e” glyph above it to show the origins of the german umlauts coming from ae, oe, ue. Text-variant may follow. \command{nyanize} A synonym for |rainbowcolor|. \command{randomerror} Just throws a random \TeX\ or \LaTeX\ error at a random time during the compilation. I have quite no idea what this could be used for. \command{randomuclc} Changes every character of the input into its uppercase or lowercase variant. Well, guess what the “random” means … @@ -220,7 +227,8 @@ The effect of the commands can be influenced, not with arguments, but only via t \command{randomcolor} Does what its name says. \command{rainbowcolor} Instead of random colors, this command causes the text color to change gradually according to the colors of a rainbow. Do not mix this with |randomcolor|, as that doesn't make any sense. \command{pancakenize} This is a dummy command that does nothing. However, every time you use it, you owe a pancake to the package author. You can either send it via mail or bring it to some (local) \TeX\ user's group meeting. -\command{substitutewords} You have to specify pairs of words by using |\addtosubstitutions{word1}{word2}|. Then call |\substitutewords| (or the other way round, doesn't matter) and each occurance of |word1| will be replaced by |word2|. You can add replacement pairs by repeated calls to |\addtosubstitutions|. Take care! This function warks with the input directly, therefore it does \emph{not} work on text that is inserted by macros, but it \emph{will} work on macro names itself! This way, you may use it to change macros (or environments) at will. Bug or feature? I'm not sure right now … +\command{substitutewords} You have to specify pairs of words by using |\addtosubstitutions{word1}{word2}|. Then call |\substitutewords| (or the other way round, doesn't matter) and each occurance of |word1| will be replaced by |word2|. You can add replacement pairs by repeated calls to |\addtosubstitutions|. Take care! This function works with the input stream directly, therefore it does \emph{not} work on text that is inserted by macros, but it \emph{will} work on macro names itself! This way, you may use it to change macros (or environments) at will. Bug or feature? I'm not sure right now … +\command{suppressonecharbreak} \TeX~normally does not suppress a linebreak after words with only one character (“I“, “a” etc.) This command suppresses line breaks. It is very similar to the code provided by the |impnattypo| package and based on the same ideas. However, the code in |chickenize| has been written before the author knew |impnattypo|, and the code differs a bit, might even be a bit faster. Well, test it! \command{tabularasa} Takes every glyph out of the document and replaces it by empty space of the same width. That could be useful if you want to hide some part of a text or similar. The |\text|-version is most likely more useful. \command{uppercasecolor} Makes every uppercase character in the input colored. At the moment, the color is randomized over the full rgb scale, but that will be adjustable once options are well implemented. \command{variantjustification} For special document types, it might be mandatory to have a fixed interword space. If you still want to have a justified type area, there must be another kind of stretchable material – one version realized by this command is using wide variants of glyphs to fill the remaining space. As the glyph substitution takes place randomly, this does \emph{not} provide the optimum justification, as this would take up much computation power. @@ -309,7 +317,7 @@ end callback.register("post_linebreak_filter",my_new_filter) \end{verbatim} -The function |callback.register| takes the name of the callback and your new function. However, there are some reasons why we avoid this syntax here. Instead, we rely on the package |luatexbase| by Manuel Pégourié-Gonnard and Élie Roux that offers the function |luatexbase.add_to_callback| which has a somewhat extended syntax: +The function |callback.register| takes the name of the callback and your new function. However, there are some reasons why we avoid this syntax here. Instead, we rely on the function |luatexbase.add_to_callback|. This is provided by the \LaTeX\ kernel table |luatexbase| which was initially a package by Manuel Pégourié-Gonnard and Élie Roux.\footnote{Since the late 2015 release of \LaTeX, the package has not to be loaded anymore since the functionality is absorbed by the kernel. Plain\TeX~users can load the |ltluatex| file which provides the needed functionality.} This function has a more extended syntax: \begin{verbatim} luatexbase.add_to_callback("post_linebreak_filter",my_new_filter,"a fancy new filter") \end{verbatim} @@ -320,21 +328,21 @@ luatexbase.remove_from_callback("post_linebreak_filter","a fancy new filter") You have to consult the Lua\TeX\ manual to see what functionality a callback has when executed, what arguments it expects and what return values have to be given. -Everything I have written here is not the complete truth – please consult the Lua\TeX\ manual and the |luatexbase| documentation for details! +Everything I have written here is not the complete truth – please consult the Lua\TeX\ manual and the |luatexbase| section in the \LaTeX\ kernel documentation for details! \section{Nodes} Essentially everything that Lua\TeX\ deals with are nodes – letters, spaces, colors, rules etc. In this package, we make heavy use of different types of nodes, so an understanding of the concept is crucial for the functionality. -A node is an object that has different properties, depending on its type which is stored in its |.id| field. For example, a node of type |glyph| has |id| 37, has a number |.char| that represents its unicode codepoint, a |.font| entry that determines the font used for this glyph, a |.height|, |.depth| and |.width| etc. +A node is an object that has different properties, depending on its type which is stored in its |.id| field. For example, a node of type |glyph| has |id| 27 (up to Lua\TeX~0.80., it was 37) has a number |.char| that represents its unicode codepoint, a |.font| entry that determines the font used for this glyph, a |.height|, |.depth| and |.width| etc. Also, a node typically has a non-empty field |.next| and |.prev|. In a list, these point to the – guess it – next or previous node. Using this, one can walk over a list of nodes step by step and manipulate the list. -A more convenient way to adress each node of a list is the function |node.traverse(head)| which takes as first argument the first node of the list. However, often one wants to adress only a certain type of nodes in a list – e.\,g. all glyphs in a vertical list that also contains glue, rules etc. This is achieved by calling the function |node.traverse_id(37,head)|, with the first argument giving the respective id of the nodes. +A more convenient way to adress each node of a list is the function |node.traverse(head)| which takes as first argument the first node of the list. However, often one wants to adress only a certain type of nodes in a list – e.\,g. all glyphs in a vertical list that also contains glue, rules etc. This is achieved by calling the function |node.traverse_id(GLYPH,head)|, with the first argument giving the respective id of the nodes.\footnote{GLYPH here stands for the id that the glyph node type has. This number can be achieved by calling |GLYPH = nodeid("glyph")| which will result in the correct number independent of the Lua\TeX~version. We will use this substitute throughout this docmuent.} The following example removes all characters “e” from the input just before paragraph breaking. This might not make any sense, but it is a good example anyways: \begin{verbatim} function remove_e(head) - for n in node.traverse_id(37,head) do + for n in node.traverse_id(GLYPH,head) do if n.char == 101 then node.remove(head,n) end @@ -367,25 +375,46 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t %\section{\TeX\ file} % This file is more-or-less a dummy file to offer a nice interface for the functions. Basically, every macro registers a function of the same name in the corresponding callback. The |un|-macros later remove these functions. Where it makes sense, there are |text|-variants that activate the function only in a certain area of the text, by means of Lua\TeX's attributes. % -% For (un)registering, we use the |luatexbase| package. Then, the |.lua| file is loaded which does the actual work. Finally, the \TeX\ macros are defined as simple |\directlua| calls. +% For (un)registering, we use the |luatexbase| \LaTeX\ kernel functionality. Then, the |.lua| file is loaded which does the actual work. Finally, the \TeX\ macros are defined as simple |\directlua| calls. % % The Lua file is not found by using a simple |dofile("chickenize.lua")| call, but we have to use kpse's |find_file|. % \begin{macrocode} -\input{luatexbase.sty} \directlua{dofile(kpse.find_file("chickenize.lua"))} +\def\ALT{% + \bgroup% + \fontspec{Latin Modern Sans}% + A% + \kern-.37em \raisebox{.7ex}{\scalebox{0.25}{L}}% + \kern-.0em \raisebox{-0.98ex}{T}% + \egroup% +} + +\def\allownumberincommands{ + \catcode`\0=11 + \catcode`\1=11 + \catcode`\2=11 + \catcode`\3=11 + \catcode`\4=11 + \catcode`\5=11 + \catcode`\6=11 + \catcode`\7=11 + \catcode`\8=11 + \catcode`\9=11 +} + \def\BEClerize{ \chickenize \directlua{ - chickenstring[1] = "noise noise" - chickenstring[2] = "atom noise" - chickenstring[3] = "shot noise" - chickenstring[4] = "photon noise" - chickenstring[5] = "camera noise" - chickenstring[6] = "noising noise" - chickenstring[7] = "thermal noise" - chickenstring[8] = "electronic noise" - chickenstring[9] = "spin noise" + chickenstring[1] = "noise noise" + chickenstring[2] = "atom noise" + chickenstring[3] = "shot noise" + chickenstring[4] = "photon noise" + chickenstring[5] = "camera noise" + chickenstring[6] = "noising noise" + chickenstring[7] = "thermal noise" + chickenstring[8] = "electronic noise" + chickenstring[9] = "spin noise" chickenstring[10] = "electron noise" chickenstring[11] = "Bogoliubov noise" chickenstring[12] = "white noise" @@ -412,13 +441,17 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t \def\unboustrophedoninverse{ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","boustrophedon_inverse")}} +\def\bubblesort{ + \directlua{luatexbase.add_to_callback("post_linebreak_filter",bubblesort,"bubblesort")}} +\def\unbubblesort{ + \directlua{luatexbase.remove_from_callback("bubblesort","bubblesort")}} + \def\chickenize{ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",chickenize,"chickenize") luatexbase.add_to_callback("start_page_number", function() texio.write("["..status.total_pages) end ,"cstartpage") luatexbase.add_to_callback("stop_page_number", function() texio.write(" chickens]") end,"cstoppage") -% luatexbase.add_to_callback("stop_run",nicetext,"a nice text") } } @@ -438,7 +471,12 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t \directlua{luatexbase.remove_from_callback("post_linebreak_filter","stretch_expansion")}} \def\countglyphs{ - \directlua{glyphnumber = 0 spacenumber = 0 + \directlua{ + counted_glyphs_by_code = {} + for i = 1,10000 do + counted_glyphs_by_code[i] = 0 + end + glyphnumber = 0 spacenumber = 0 luatexbase.add_to_callback("post_linebreak_filter",countglyphs,"countglyphs") luatexbase.add_to_callback("stop_run",printglyphnumber,"printglyphnumber") } @@ -531,6 +569,19 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t \def\unleetspeak{ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","1337")}} +\def\leftsideright#1{ + \directlua{luatexbase.add_to_callback("pre_linebreak_filter",leftsideright,"leftsideright")} + \directlua{ + leftsiderightindex = {#1} + leftsiderightarray = {} + for _,i in pairs(leftsiderightindex) do + leftsiderightarray[i] = true + end + } +} +\def\unleftsideright{ + \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","leftsideright")}} + \def\letterspaceadjust{ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",letterspaceadjust,"letterspaceadjust")}} \def\unletterspaceadjust{ @@ -550,13 +601,18 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t \def\matrixize{ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",matrixize,"matrixize")}} \def\unmatrixize{ - \directlua{luatexbase.remove_from_callback("pre_linebreak_filter",matrixize)}} + \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","matrixize")}} \def\milkcow{ %% FIXME %% to be implemented \directlua{}} \def\unmilkcow{ \directlua{}} +\def\medievalumlaut{ + \directlua{luatexbase.add_to_callback("post_linebreak_filter",medievalumlaut,"medievalumlaut")}} +\def\unmedievalumlaut{ + \directlua{luatexbase.remove_from_callback("post_linebreak_filter","medievalumlaut")}} + \def\pancakenize{ \directlua{luatexbase.add_to_callback("stop_run",pancaketext,"pancaketext")}} @@ -566,8 +622,8 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t \def\unrainbowcolor{ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","rainbowcolor") rainbowcolor = false}} - \let\nyanize\rainbowcolor - \let\unnyanize\unrainbowcolor +\let\nyanize\rainbowcolor +\let\unnyanize\unrainbowcolor \def\randomcolor{ \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomcolor,"randomcolor")}} @@ -611,16 +667,42 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t \directlua{addtosubstitutions("#1","#2")} } +\def\suppressonecharbreak{ + \directlua{luatexbase.add_to_callback("pre_linebreak_filter",suppressonecharbreak,"suppressonecharbreak")}} +\def\unsuppressonecharbreak{ + \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","suppressonecharbreak")}} + \def\tabularasa{ \directlua{luatexbase.add_to_callback("post_linebreak_filter",tabularasa,"tabularasa")}} \def\untabularasa{ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","tabularasa")}} +\def\tanjanize{ + \directlua{luatexbase.add_to_callback("post_linebreak_filter",tanjanize,"tanjanize")}} +\def\untanjanize{ + \directlua{luatexbase.remove_from_callback("post_linebreak_filter","tanjanize")}} + \def\uppercasecolor{ \directlua{luatexbase.add_to_callback("post_linebreak_filter",uppercasecolor,"uppercasecolor")}} \def\unuppercasecolor{ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","uppercasecolor")}} +\def\upsidedown#1{ + \directlua{luatexbase.add_to_callback("post_linebreak_filter",upsidedown,"upsidedown")} + \directlua{ + upsidedownindex = {#1} + upsidedownarray = {} + for _,i in pairs(upsidedownindex) do + upsidedownarray[i] = true + end + } +} +\def\unupsidedown{ + \directlua{luatexbase.remove_from_callback("post_linebreak_filter","upsidedown")}} + +\def\unuppercasecolor{ + \directlua{luatexbase.remove_from_callback("post_linebreak_filter","upsidedow")}} + \def\variantjustification{ \directlua{luatexbase.add_to_callback("post_linebreak_filter",variantjustification,"variantjustification")}} \def\unvariantjustification{ @@ -633,13 +715,13 @@ The namespace of the chickenize package is \emph{not} consistent. Please don't t % \end{macrocode} % Now the setup for the |\text|-versions. We utilize Lua\TeX s attributes to mark all nodes that should be manipulated. The macros should be |\long| to allow arbitrary input. % \begin{macrocode} -\newluatexattribute\leetattr -\newluatexattribute\letterspaceadjustattr -\newluatexattribute\randcolorattr -\newluatexattribute\randfontsattr -\newluatexattribute\randuclcattr -\newluatexattribute\tabularasaattr -\newluatexattribute\uppercasecolorattr +\newattribute\leetattr +\newattribute\letterspaceadjustattr +\newattribute\randcolorattr +\newattribute\randfontsattr +\newattribute\randuclcattr +\newattribute\tabularasaattr +\newattribute\uppercasecolorattr \long\def\textleetspeak#1% {\setluatexattribute\leetattr{42}#1\unsetluatexattribute\leetattr} @@ -727,9 +809,13 @@ sloppyline(flugel_vorne,flugel_unten) sloppyline(flugel_hinten,flugel_unten) % Some code might be implemented to manipulate figures for full chickenization. However, I will \emph{not} load any packages at this place, as loading of expl3 or TikZ or whatever takes too much time for such a tiny package like this one. If you require any of the features presented here, you have to load the packages on your own. Maybe this will change. % \begin{macrocode} \ProvidesPackage{chickenize}% - [2013/08/22 v0.2.1a chickenize package] + [2015/12/26 v0.2.2 chickenize package] \input{chickenize} % \end{macrocode} +% \subsection{Free Compliments} +% \begin{macrocode} + +% \end{macrocode} % \subsection{Definition of User-Level Macros} % Nothing done so far, just some minor ideas. If you want to implement some cool things, contact me! :) % \begin{macrocode} @@ -767,10 +853,11 @@ local nodetraverseid = node.traverse_id local nodeslide = node.slide Hhead = nodeid("hhead") -RULE = nodeid("rule") -GLUE = nodeid("glue") -WHAT = nodeid("whatsit") -COL = node.subtype("pdf_colorstack") +RULE = nodeid("rule") +GLUE = nodeid("glue") +WHAT = nodeid("whatsit") +COL = node.subtype("pdf_colorstack") +PDF_LITERAL = node.subtype("pdf_literal") GLYPH = nodeid("glyph") % \end{macrocode} % Now we set up the nodes used for all color things. The nodes are whatsits of subtype |pdf_colorstack|. @@ -800,7 +887,7 @@ chickenize_ignore_word = false % The function |chickenize_real_stuff| is started once the beginning of a to-be-substituted word is found. % \begin{macrocode} chickenize_real_stuff = function(i,head) - while ((i.next.id == 37) or (i.next.id == 11) or (i.next.id == 7) or (i.next.id == 0)) do --find end of a word + while ((i.next.id == GLYPH) or (i.next.id == 11) or (i.next.id == 7) or (i.next.id == 0)) do --find end of a word i.next = i.next.next end @@ -810,9 +897,9 @@ chickenize_real_stuff = function(i,head) -- But it could be done only once each paragraph as in-paragraph changes are not possible! chickenstring_tmp = chickenstring[math.random(1,#chickenstring)] - chicken[0] = nodenew(37,1) -- only a dummy for the loop + chicken[0] = nodenew(GLYPH,1) -- only a dummy for the loop for i = 1,string.len(chickenstring_tmp) do - chicken[i] = nodenew(37,1) + chicken[i] = nodenew(GLYPH,1) chicken[i].font = font.current() chicken[i-1].next = chicken[i] end @@ -849,23 +936,23 @@ chickenize_real_stuff = function(i,head) end chickenize = function(head) - for i in nodetraverseid(37,head) do --find start of a word + for i in nodetraverseid(GLYPH,head) do --find start of a word + -- Random determination of the chickenization of the next word: + if math.random() > chickenizefraction then + chickenize_ignore_word = true + elseif chickencount then + chicken_substitutions = chicken_substitutions + 1 + end + if (chickenize_ignore_word == false) then -- normal case: at the beginning of a word, we jump into chickenization if (i.char > 64 and i.char < 91) then chickenize_capital = true else chickenize_capital = false end head = chickenize_real_stuff(i,head) end -- At the end of the word, the ignoring is reset. New chance for everyone. - if not((i.next.id == 37) or (i.next.id == 7) or (i.next.id == 22) or (i.next.id == 11)) then + if not((i.next.id == GLYPH) or (i.next.id == 7) or (i.next.id == 22) or (i.next.id == 11)) then chickenize_ignore_word = false end - --- And the random determination of the chickenization of the next word: - if math.random() > chickenizefraction then - chickenize_ignore_word = true - elseif chickencount then - chicken_substitutions = chicken_substitutions + 1 - end end return head end @@ -896,8 +983,8 @@ end % Linewise rotation: % \begin{macrocode} boustrophedon = function(head) - rot = node.new(8,8) - rot2 = node.new(8,8) + rot = node.new(8,PDF_LITERAL) + rot2 = node.new(8,PDF_LITERAL) odd = true for line in node.traverse_id(0,head) do if odd == false then @@ -918,12 +1005,12 @@ end % \begin{macrocode} boustrophedon_glyphs = function(head) odd = false - rot = nodenew(8,8) - rot2 = nodenew(8,8) + rot = nodenew(8,PDF_LITERAL) + rot2 = nodenew(8,PDF_LITERAL) for line in nodetraverseid(0,head) do if odd==true then line.dir = "TRT" - for g in nodetraverseid(37,line.head) do + for g in nodetraverseid(GLYPH,line.head) do w = -g.width/65536*0.99625 rot.data = "-1 0 0 1 " .. w .." 0 cm" rot2.data = "-1 0 0 1 " .. -w .." 0 cm" @@ -942,8 +1029,8 @@ end % Inverse boustrophedon. At least I think, this is the way Rongorongo is written. However, the top-to-bottom direction has to be inverted, too. % \begin{macrocode} boustrophedon_inverse = function(head) - rot = node.new(8,8) - rot2 = node.new(8,8) + rot = node.new(8,PDF_LITERAL) + rot2 = node.new(8,PDF_LITERAL) odd = true for line in node.traverse_id(0,head) do if odd == false then @@ -963,17 +1050,37 @@ texio.write_nl(line.height) end % \end{macrocode} % +% \subsection{bubblesort}\label{sec:bubblesort} +% \begin{macrocode} +function bubblesort(head) + for line in nodetraverseid(0,head) do + for glyph in nodetraverseid(GLYPH,line.head) do + + end + end + return head +end +% \end{macrocode} % \subsection{countglyphs}\label{sec:countglyphs} -% Counts the glyphs in your document. Where “glyph” means every printed character in everything that is a paragraph – formulas do \emph{not} work! However, hyphenations \emph{do} work and the hyphen sign \emph{is counted}! And that is the sole reason for this function – every simple script could read the letters in a doucment, but only after the hyphenation it is possible to count the real number of printed characters – where the hyphen does count. Also, spaces are count, but only spaces between glyphs in the output (i.\,e. nothing at the end/beginning of the lines), excluding indentation. +% Counts the glyphs in your document. Where “glyph” means every printed character in everything that is a paragraph – formulas do \emph{not} work! Captions of floats etc.~also will \emph{not} work. However, hyphenations \emph{do} work and the hyphen sign \emph{is counted}! And that is the sole reason for this function – every simple script could read the letters in a doucment, but only after the hyphenation it is possible to count the real number of printed characters – where the hyphen does count. +% +% Not only the total number of glyphs is recorded, but also the number of glyphs by character code. By this, you know exactly how many “a” or “ß” you used. A feature of category “completely useless”. +% +% Spaces are also counted, but only spaces between glyphs in the output (i.\,e.~nothing at the end/beginning of the lines), excluding indentation. % -% This function will (maybe, upon request) be extended to allow counting of whatever you want. +% This function will (maybe, upon request) be extended to allow counting of whatever you want. +% +%% Take care: This will slow down the compilation extremely, by about a factor of 2! Only use for playing around or counting a final version of your document! % \begin{macrocode} countglyphs = function(head) for line in nodetraverseid(0,head) do - for glyph in nodetraverseid(37,line.head) do + for glyph in nodetraverseid(GLYPH,line.head) do glyphnumber = glyphnumber + 1 - if (glyph.next.id == 10) and (glyph.next.next.id ==37) then - spacenumber = spacenumber + 1 + if (glyph.next.next) then + if (glyph.next.id == 10) and (glyph.next.next.id == GLYPH) then + spacenumber = spacenumber + 1 + end + counted_glyphs_by_code[glyph.char] = counted_glyphs_by_code[glyph.char] + 1 end end end @@ -983,7 +1090,12 @@ end % To print out the number at the end of the document, the following function is registered in the |stop_run| callback. This will prevent the normal message from being printed, informing the user about page and memory stats etc. But I guess when counting characters, everything else does not matter at all? … % \begin{macrocode} printglyphnumber = function() - texiowrite_nl("\nNumber of glyphs in this document: "..glyphnumber) + texiowrite_nl("\nNumber of glyphs by character code (only up to 127):") + for i = 1,127 do --%% FIXME: should allow for more characters, but cannot be printed to console output – print into document? + texiowrite_nl(string.char(i)..": "..counted_glyphs_by_code[i]) + end + + texiowrite_nl("\nTotal number of glyphs in this document: "..glyphnumber) texiowrite_nl("Number of spaces in this document: "..spacenumber) texiowrite_nl("Glyphs plus spaces: "..glyphnumber+spacenumber.."\n") end @@ -992,7 +1104,7 @@ end % Counts the number of words in the document. The function works directly before the line breaking, so all macros are expanded. A “word” then is everything that is between two spaces before paragraph formatting. The beginning of a paragraph is a word, and the last word of a paragraph is accounted for by explicit increasing the counter, as no space token follows. % \begin{macrocode} countwords = function(head) - for glyph in nodetraverseid(37,head) do + for glyph in nodetraverseid(GLYPH,head) do if (glyph.next.id == 10) then wordnumber = wordnumber + 1 end @@ -1009,14 +1121,14 @@ end % \end{macrocode} % \subsection{detectdoublewords}\label{sec:detectdoublewords} -% \begin{macrocode} +% \begin{macrocode} %% FIXME: Does this work? … function detectdoublewords(head) prevlastword = {} -- array of numbers representing the glyphs prevfirstword = {} newlastword = {} newfirstword = {} for line in nodetraverseid(0,head) do - for g in nodetraverseid(37,line.head) do + for g in nodetraverseid(GLYPH,line.head) do texio.write_nl("next glyph",#newfirstword+1) newfirstword[#newfirstword+1] = g.char if (g.next.id == 10) then break end @@ -1182,6 +1294,24 @@ leet = function(head) return head end % \end{macrocode} +% \subsection{leftsideright}\label{sec:leftsideright} +% This function mirrors each glyph given in the array of \verb|leftsiderightarray| horizontally. +% \begin{macrocode} +leftsideright = function(head) + local factor = 65536/0.99626 + for n in nodetraverseid(GLYPH,head) do + if (leftsiderightarray[n.char]) then + shift = nodenew(8,PDF_LITERAL) + shift2 = nodenew(8,PDF_LITERAL) + shift.data = "q -1 0 0 1 " .. n.width/factor .." 0 cm" + shift2.data = "Q 1 0 0 1 " .. n.width/factor .." 0 cm" + nodeinsertbefore(head,n,shift) + nodeinsertafter(head,n,shift2) + end + end + return head +end +% \end{macrocode} % \subsection{letterspaceadjust}\label{sec:letterspaceadjust} % Yet another piece of code by Paul. This is primarily inteded for very narrow columns, but may also increase the overall quality of typesetting. Basically, it does nothing else than adding expandable space \emph{between} letters. This way, the amount of stretching between words can be reduced which will, hopefully, result in the greyness to be more equally distributed over the page. % @@ -1252,6 +1382,54 @@ matrixize = function(head) return head end % \end{macrocode} +% \subsection{medievalumlaut}\label{sec:medievalumlaut} +% Changes the umlauts ä, ö, ü into a, o, u with an e as an accent. The exact position of the e is adapted for each glyph, but that is only tested with one font. Other fonts might f*ck up everything. +% +% For this, we define node representing the e (which then is copied every time) and two nodes that shift the e to where it belongs by using pdf matrix-nodes. An additional kern node shifts the space that the e took back so that everything ends up in the right place. All this happens in the \verb|post_linebreak_filter| to enable normal hyphenation and line breaking. Well, \verb|pre_linebreak_filter| would also have done … +% \begin{macrocode} +medievalumlaut = function(head) + local factor = 65536/0.99626 + local org_e_node = nodenew(GLYPH) + org_e_node.char = 101 + for line in nodetraverseid(0,head) do + for n in nodetraverseid(GLYPH,line.head) do + if (n.char == 228 or n.char == 246 or n.char == 252) then + e_node = nodecopy(org_e_node) + e_node.font = n.font + shift = nodenew(8,PDF_LITERAL) + shift2 = nodenew(8,PDF_LITERAL) + shift2.data = "Q 1 0 0 1 " .. e_node.width/factor .." 0 cm" + nodeinsertafter(head,n,e_node) + + nodeinsertbefore(head,e_node,shift) + nodeinsertafter(head,e_node,shift2) + + x_node = nodenew(11) + x_node.kern = -e_node.width + nodeinsertafter(head,shift2,x_node) + end + + if (n.char == 228) then -- ä + shift.data = "q 0.5 0 0 0.5 " .. + -n.width/factor*0.85 .." ".. n.height/factor*0.75 .. " cm" + n.char = 97 + end + if (n.char == 246) then -- ö + shift.data = "q 0.5 0 0 0.5 " .. + -n.width/factor*0.75 .." ".. n.height/factor*0.75 .. " cm" + n.char = 111 + end + if (n.char == 252) then -- ü + shift.data = "q 0.5 0 0 0.5 " .. + -n.width/factor*0.75 .." ".. n.height/factor*0.75 .. " cm" + n.char = 117 + end + end + end + return head +end +% \end{macrocode} +% % \subsection{pancakenize}\label{sec:pancakenize} % \begin{macrocode} local separator = string.rep("=", 28) @@ -1301,7 +1479,7 @@ end % \begin{macrocode} uclcratio = 0.5 -- ratio between uppercase and lower case randomuclc = function(head) - for i in nodetraverseid(37,head) do + for i in nodetraverseid(GLYPH,head) do if not(randomuclc_onlytext) or node.has_attribute(i,luatexbase.attributes.randuclcattr) then if math.random() < uclcratio then i.char = tex.uccode[i.char] @@ -1387,7 +1565,7 @@ end % \begin{macrocode} randomcolor = function(head) for line in nodetraverseid(0,head) do - for i in nodetraverseid(37,line.head) do + for i in nodetraverseid(GLYPH,line.head) do if not(randomcolor_onlytext) or (node.has_attribute(i,luatexbase.attributes.randcolorattr)) then @@ -1407,6 +1585,7 @@ end % \subsection{rickroll}\label{sec:rickroll} % Another tribute to pop culture. Either: substitute word-by-word as in pancake. OR: substitute each link to a youtube-rickroll … % \begin{macrocode} +% % \end{macrocode} % \subsection{substitutewords}\label{sec:substitutewords} % This function is one of the rather usefull ones of this package. It replaces each occurance of one word by another word, which both are specified by the user. So nothing random or funny, but a real serious function! There are three levels for this function: At user-level, the user just specifies two strings that are passed to the function |addtosubstitutions|. This is needed as the |#| has a special meaning both in \TeX s definitions and in Lua. In this second step, the list of substitutions is just extended, and the real work is done by the function |substiuteword| which is registered in the |process_input_buffer| callback. Once the substitution list is built, the rest is very simple: We just use |gsub| to substitute, do this for every item in the list, and that's it. @@ -1426,6 +1605,24 @@ substitutewords = function(head) return head end % \end{macrocode} +% \subsection{suppressonecharbreak}\label{sec:suppressonecharbreak} +% We rush through the node list before line breaking takes place and insert large penalties for breaks after single glyphs. To keep the code as small, simple and fast as possible, we |traverse_id| over spaces and see wether the |next.next| node is also a space. This might not be the best and most universal way of doing it, but the simplest. The penalty is not created newly each time, but copied – no significant speed gain, however. +% \begin{macrocode} +suppressonecharbreakpenaltynode = node.new(12) +suppressonecharbreakpenaltynode.penalty = 10000 +% \end{macrocode} +% \begin{macrocode} +function suppressonecharbreak(head) + for i in node.traverse_id(10,head) do + if ((i.next) and (i.next.next.id == 10)) then + pen = node.copy(suppressonecharbreakpenaltynode) + node.insert_after(head,i.next,pen) + end + end + + return head +end +% \end{macrocode} % \subsection{tabularasa}\label{sec:tabularasa} % Removes every glyph from the output and replaces it by empty space. In the end, next to nothing will be visible. Should be extended to also remove rules or just anything visible. % \begin{macrocode} @@ -1445,6 +1642,47 @@ tabularasa = function(head) return head end % \end{macrocode} +% \subsection{tanjanize}\label{sec:tanjanize} +% \begin{macrocode} +tanjanize = function(head) + local s = nodenew(nodeid"kern") + local m = nodenew(GLYPH,1) + local use_letter_i = true + scale = nodenew(8,PDF_LITERAL) + scale2 = nodenew(8,PDF_LITERAL) + scale.data = "0.5 0 0 0.5 0 0 cm" + scale2.data = "2 0 0 2 0 0 cm" + + for line in nodetraverseid(nodeid"hlist",head) do + for n in nodetraverseid(nodeid"glyph",line.head) do + mimicount = 0 + tmpwidth = 0 + while ((n.next.id == GLYPH) or (n.next.id == 11) or (n.next.id == 7) or (n.next.id == 0)) do --find end of a word + n.next = n.next.next + mimicount = mimicount + 1 + tmpwidth = tmpwidth + n.width + end + + mimi = {} -- constructing the node list. + mimi[0] = nodenew(GLYPH,1) -- only a dummy for the loop + for i = 1,string.len(mimicount) do + mimi[i] = nodenew(GLYPH,1) + mimi[i].font = font.current() + if(use_letter_i) then mimi[i].char = 109 else mimi[i].char = 105 end + use_letter_i = not(use_letter_i) + mimi[i-1].next = mimi[i] + end +--]] + +line.head = nodeinsertbefore(line.head,n,nodecopy(scale)) +nodeinsertafter(line.head,n,nodecopy(scale2)) + s.kern = (tmpwidth*2-n.width) + nodeinsertafter(line.head,n,nodecopy(s)) + end + end + return head +end +% \end{macrocode} % \subsection{uppercasecolor}\label{sec:uppercasecolor} % Loop through all the nodes and checking whether it is uppercase. If so (and also for small caps), color it. % \begin{macrocode} @@ -1466,6 +1704,26 @@ uppercasecolor = function (head) return head end % \end{macrocode} +% \subsection{upsidedown}\label{sec:upsidedown} +% This function mirrors all glyphs given in the array \verb|upsidedownarray| vertically. +% \begin{macrocode} +upsidedown = function(head) + local factor = 65536/0.99626 + for line in nodetraverseid(Hhead,head) do + for n in nodetraverseid(GLYPH,line.head) do + if (upsidedownarray[n.char]) then + shift = nodenew(8,PDF_LITERAL) + shift2 = nodenew(8,PDF_LITERAL) + shift.data = "q 1 0 0 -1 0 " .. n.height/factor .." cm" + shift2.data = "Q 1 0 0 1 " .. n.width/factor .." 0 cm" + nodeinsertbefore(head,n,shift) + nodeinsertafter(head,n,shift2) + end + end + end + return head +end +% \end{macrocode} % \subsection{colorstretch}\label{sec:colorstretch} % This function displays the amount of stretching that has been done for each line of an arbitrary document. A well-typeset document should be equally grey over all lines, which is not always possible. % @@ -1501,8 +1759,8 @@ colorstretch = function (head) if colorexpansion then -- if also the font expansion should be shown local g = line.head - while not(g.id == 37) and (g.next) do g = g.next end -- find first glyph on line. If line is empty, no glyph: - if (g.id == 37) then -- read width only if g is a glyph! + while not(g.id == GLYPH) and (g.next) do g = g.next end -- find first glyph on line. If line is empty, no glyph: + if (g.id == GLYPH) then -- read width only if g is a glyph! exp_factor = g.width / f[g.char].width exp_color = colorstretch_coloroffset + (1-exp_factor)*10 .. " g" rule_bad.width = 0.5*line.width -- we need two rules on each line! @@ -1565,7 +1823,7 @@ colorstretch = function (head) glue_ratio_output = {} for s in string.utfvalues(math.abs(glue_ratio)) do -- using math.abs here gets us rid of the minus sign local char = unicode.utf8.char(s) - glue_ratio_output[j] = nodenew(37,1) + glue_ratio_output[j] = nodenew(GLYPH,1) glue_ratio_output[j].font = font.current() glue_ratio_output[j].char = s j = j+1 @@ -1815,4 +2073,4 @@ end % % Special thanks go to Paul “we could have chickenized the world” Isambert who contributed a lot of ideas, code and bug fixes and made much of the code executable at all. I also thank Philipp Gesang who gave me many advices on the Lua code – which I still didn't have time to correct … % \Finale -% \endinput +% \endinput
\ No newline at end of file diff --git a/Master/texmf-dist/tex/luatex/chickenize/chickenize.lua b/Master/texmf-dist/tex/luatex/chickenize/chickenize.lua index 6a2b3f648db..8043148a62d 100644 --- a/Master/texmf-dist/tex/luatex/chickenize/chickenize.lua +++ b/Master/texmf-dist/tex/luatex/chickenize/chickenize.lua @@ -8,7 +8,7 @@ -- -- EXPERIMENTAL CODE -- --- This package is copyright © 2013 Arno L. Trautmann. It may be distributed and/or +-- This package is copyright © 2015 Arno L. Trautmann. It may be distributed and/or -- modified under the conditions of the LaTeX Project Public License, either version 1.3c -- of this license or (at your option) any later version. This work has the LPPL mainten- -- ance status ‘maintained’. @@ -24,10 +24,11 @@ local nodetraverseid = node.traverse_id local nodeslide = node.slide Hhead = nodeid("hhead") -RULE = nodeid("rule") -GLUE = nodeid("glue") -WHAT = nodeid("whatsit") -COL = node.subtype("pdf_colorstack") +RULE = nodeid("rule") +GLUE = nodeid("glue") +WHAT = nodeid("whatsit") +COL = node.subtype("pdf_colorstack") +PDF_LITERAL = node.subtype("pdf_literal") GLYPH = nodeid("glyph") color_push = nodenew(WHAT,COL) color_pop = nodenew(WHAT,COL) @@ -47,7 +48,7 @@ chicken_substitutions = 0 -- value to count the substituted chickens. Makes sens local match = unicode.utf8.match chickenize_ignore_word = false chickenize_real_stuff = function(i,head) - while ((i.next.id == 37) or (i.next.id == 11) or (i.next.id == 7) or (i.next.id == 0)) do --find end of a word + while ((i.next.id == GLYPH) or (i.next.id == 11) or (i.next.id == 7) or (i.next.id == 0)) do --find end of a word i.next = i.next.next end @@ -57,9 +58,9 @@ chickenize_real_stuff = function(i,head) -- But it could be done only once each paragraph as in-paragraph changes are not possible! chickenstring_tmp = chickenstring[math.random(1,#chickenstring)] - chicken[0] = nodenew(37,1) -- only a dummy for the loop + chicken[0] = nodenew(GLYPH,1) -- only a dummy for the loop for i = 1,string.len(chickenstring_tmp) do - chicken[i] = nodenew(37,1) + chicken[i] = nodenew(GLYPH,1) chicken[i].font = font.current() chicken[i-1].next = chicken[i] end @@ -96,23 +97,23 @@ chickenize_real_stuff = function(i,head) end chickenize = function(head) - for i in nodetraverseid(37,head) do --find start of a word + for i in nodetraverseid(GLYPH,head) do --find start of a word + -- Random determination of the chickenization of the next word: + if math.random() > chickenizefraction then + chickenize_ignore_word = true + elseif chickencount then + chicken_substitutions = chicken_substitutions + 1 + end + if (chickenize_ignore_word == false) then -- normal case: at the beginning of a word, we jump into chickenization if (i.char > 64 and i.char < 91) then chickenize_capital = true else chickenize_capital = false end head = chickenize_real_stuff(i,head) end -- At the end of the word, the ignoring is reset. New chance for everyone. - if not((i.next.id == 37) or (i.next.id == 7) or (i.next.id == 22) or (i.next.id == 11)) then + if not((i.next.id == GLYPH) or (i.next.id == 7) or (i.next.id == 22) or (i.next.id == 11)) then chickenize_ignore_word = false end - --- And the random determination of the chickenization of the next word: - if math.random() > chickenizefraction then - chickenize_ignore_word = true - elseif chickencount then - chicken_substitutions = chicken_substitutions + 1 - end end return head end @@ -134,8 +135,8 @@ nicetext = function() end end boustrophedon = function(head) - rot = node.new(8,8) - rot2 = node.new(8,8) + rot = node.new(8,PDF_LITERAL) + rot2 = node.new(8,PDF_LITERAL) odd = true for line in node.traverse_id(0,head) do if odd == false then @@ -153,12 +154,12 @@ boustrophedon = function(head) end boustrophedon_glyphs = function(head) odd = false - rot = nodenew(8,8) - rot2 = nodenew(8,8) + rot = nodenew(8,PDF_LITERAL) + rot2 = nodenew(8,PDF_LITERAL) for line in nodetraverseid(0,head) do if odd==true then line.dir = "TRT" - for g in nodetraverseid(37,line.head) do + for g in nodetraverseid(GLYPH,line.head) do w = -g.width/65536*0.99625 rot.data = "-1 0 0 1 " .. w .." 0 cm" rot2.data = "-1 0 0 1 " .. -w .." 0 cm" @@ -174,8 +175,8 @@ boustrophedon_glyphs = function(head) return head end boustrophedon_inverse = function(head) - rot = node.new(8,8) - rot2 = node.new(8,8) + rot = node.new(8,PDF_LITERAL) + rot2 = node.new(8,PDF_LITERAL) odd = true for line in node.traverse_id(0,head) do if odd == false then @@ -193,24 +194,41 @@ texio.write_nl(line.height) end return head end +function bubblesort(head) + for line in nodetraverseid(0,head) do + for glyph in nodetraverseid(GLYPH,line.head) do + + end + end + return head +end +-- Take care: This will slow down the compilation extremely, by about a factor of 2! Only use for playing around or counting a final version of your document! countglyphs = function(head) for line in nodetraverseid(0,head) do - for glyph in nodetraverseid(37,line.head) do + for glyph in nodetraverseid(GLYPH,line.head) do glyphnumber = glyphnumber + 1 - if (glyph.next.id == 10) and (glyph.next.next.id ==37) then - spacenumber = spacenumber + 1 + if (glyph.next.next) then + if (glyph.next.id == 10) and (glyph.next.next.id == GLYPH) then + spacenumber = spacenumber + 1 + end + counted_glyphs_by_code[glyph.char] = counted_glyphs_by_code[glyph.char] + 1 end end end return head end printglyphnumber = function() - texiowrite_nl("\nNumber of glyphs in this document: "..glyphnumber) + texiowrite_nl("\nNumber of glyphs by character code (only up to 127):") + for i = 1,127 do --%% FIXME: should allow for more characters, but cannot be printed to console output – print into document? + texiowrite_nl(string.char(i)..": "..counted_glyphs_by_code[i]) + end + + texiowrite_nl("\nTotal number of glyphs in this document: "..glyphnumber) texiowrite_nl("Number of spaces in this document: "..spacenumber) texiowrite_nl("Glyphs plus spaces: "..glyphnumber+spacenumber.."\n") end countwords = function(head) - for glyph in nodetraverseid(37,head) do + for glyph in nodetraverseid(GLYPH,head) do if (glyph.next.id == 10) then wordnumber = wordnumber + 1 end @@ -228,7 +246,7 @@ function detectdoublewords(head) newlastword = {} newfirstword = {} for line in nodetraverseid(0,head) do - for g in nodetraverseid(37,line.head) do + for g in nodetraverseid(GLYPH,line.head) do texio.write_nl("next glyph",#newfirstword+1) newfirstword[#newfirstword+1] = g.char if (g.next.id == 10) then break end @@ -359,6 +377,20 @@ leet = function(head) end return head end +leftsideright = function(head) + local factor = 65536/0.99626 + for n in nodetraverseid(GLYPH,head) do + if (leftsiderightarray[n.char]) then + shift = nodenew(8,PDF_LITERAL) + shift2 = nodenew(8,PDF_LITERAL) + shift.data = "q -1 0 0 1 " .. n.width/factor .." 0 cm" + shift2.data = "Q 1 0 0 1 " .. n.width/factor .." 0 cm" + nodeinsertbefore(head,n,shift) + nodeinsertafter(head,n,shift2) + end + end + return head +end local letterspace_glue = nodenew(nodeid"glue") local letterspace_spec = nodenew(nodeid"glue_spec") local letterspace_pen = nodenew(nodeid"penalty") @@ -411,6 +443,47 @@ matrixize = function(head) end return head end +medievalumlaut = function(head) + local factor = 65536/0.99626 + local org_e_node = nodenew(GLYPH) + org_e_node.char = 101 + for line in nodetraverseid(0,head) do + for n in nodetraverseid(GLYPH,line.head) do + if (n.char == 228 or n.char == 246 or n.char == 252) then + e_node = nodecopy(org_e_node) + e_node.font = n.font + shift = nodenew(8,PDF_LITERAL) + shift2 = nodenew(8,PDF_LITERAL) + shift2.data = "Q 1 0 0 1 " .. e_node.width/factor .." 0 cm" + nodeinsertafter(head,n,e_node) + + nodeinsertbefore(head,e_node,shift) + nodeinsertafter(head,e_node,shift2) + + x_node = nodenew(11) + x_node.kern = -e_node.width + nodeinsertafter(head,shift2,x_node) + end + + if (n.char == 228) then -- ä + shift.data = "q 0.5 0 0 0.5 " .. + -n.width/factor*0.85 .." ".. n.height/factor*0.75 .. " cm" + n.char = 97 + end + if (n.char == 246) then -- ö + shift.data = "q 0.5 0 0 0.5 " .. + -n.width/factor*0.75 .." ".. n.height/factor*0.75 .. " cm" + n.char = 111 + end + if (n.char == 252) then -- ü + shift.data = "q 0.5 0 0 0.5 " .. + -n.width/factor*0.75 .." ".. n.height/factor*0.75 .. " cm" + n.char = 117 + end + end + end + return head +end local separator = string.rep("=", 28) local texiowrite_nl = texio.write_nl pancaketext = function() @@ -446,7 +519,7 @@ randomfonts = function(head) end uclcratio = 0.5 -- ratio between uppercase and lower case randomuclc = function(head) - for i in nodetraverseid(37,head) do + for i in nodetraverseid(GLYPH,head) do if not(randomuclc_onlytext) or node.has_attribute(i,luatexbase.attributes.randuclcattr) then if math.random() < uclcratio then i.char = tex.uccode[i.char] @@ -514,7 +587,7 @@ randomcolorstring = function() end randomcolor = function(head) for line in nodetraverseid(0,head) do - for i in nodetraverseid(37,line.head) do + for i in nodetraverseid(GLYPH,line.head) do if not(randomcolor_onlytext) or (node.has_attribute(i,luatexbase.attributes.randcolorattr)) then @@ -540,6 +613,18 @@ substitutewords = function(head) end return head end +suppressonecharbreakpenaltynode = node.new(12) +suppressonecharbreakpenaltynode.penalty = 10000 +function suppressonecharbreak(head) + for i in node.traverse_id(10,head) do + if ((i.next) and (i.next.next.id == 10)) then + pen = node.copy(suppressonecharbreakpenaltynode) + node.insert_after(head,i.next,pen) + end + end + + return head +end tabularasa_onlytext = false tabularasa = function(head) @@ -555,6 +640,44 @@ tabularasa = function(head) end return head end +tanjanize = function(head) + local s = nodenew(nodeid"kern") + local m = nodenew(GLYPH,1) + local use_letter_i = true + scale = nodenew(8,PDF_LITERAL) + scale2 = nodenew(8,PDF_LITERAL) + scale.data = "0.5 0 0 0.5 0 0 cm" + scale2.data = "2 0 0 2 0 0 cm" + + for line in nodetraverseid(nodeid"hlist",head) do + for n in nodetraverseid(nodeid"glyph",line.head) do + mimicount = 0 + tmpwidth = 0 + while ((n.next.id == GLYPH) or (n.next.id == 11) or (n.next.id == 7) or (n.next.id == 0)) do --find end of a word + n.next = n.next.next + mimicount = mimicount + 1 + tmpwidth = tmpwidth + n.width + end + + mimi = {} -- constructing the node list. + mimi[0] = nodenew(GLYPH,1) -- only a dummy for the loop + for i = 1,string.len(mimicount) do + mimi[i] = nodenew(GLYPH,1) + mimi[i].font = font.current() + if(use_letter_i) then mimi[i].char = 109 else mimi[i].char = 105 end + use_letter_i = not(use_letter_i) + mimi[i-1].next = mimi[i] + end +--]] + +line.head = nodeinsertbefore(line.head,n,nodecopy(scale)) +nodeinsertafter(line.head,n,nodecopy(scale2)) + s.kern = (tmpwidth*2-n.width) + nodeinsertafter(line.head,n,nodecopy(s)) + end + end + return head +end uppercasecolor_onlytext = false uppercasecolor = function (head) @@ -572,6 +695,22 @@ uppercasecolor = function (head) end return head end +upsidedown = function(head) + local factor = 65536/0.99626 + for line in nodetraverseid(Hhead,head) do + for n in nodetraverseid(GLYPH,line.head) do + if (upsidedownarray[n.char]) then + shift = nodenew(8,PDF_LITERAL) + shift2 = nodenew(8,PDF_LITERAL) + shift.data = "q 1 0 0 -1 0 " .. n.height/factor .." cm" + shift2.data = "Q 1 0 0 1 " .. n.width/factor .." 0 cm" + nodeinsertbefore(head,n,shift) + nodeinsertafter(head,n,shift2) + end + end + end + return head +end keeptext = true colorexpansion = true @@ -590,8 +729,8 @@ colorstretch = function (head) if colorexpansion then -- if also the font expansion should be shown local g = line.head - while not(g.id == 37) and (g.next) do g = g.next end -- find first glyph on line. If line is empty, no glyph: - if (g.id == 37) then -- read width only if g is a glyph! + while not(g.id == GLYPH) and (g.next) do g = g.next end -- find first glyph on line. If line is empty, no glyph: + if (g.id == GLYPH) then -- read width only if g is a glyph! exp_factor = g.width / f[g.char].width exp_color = colorstretch_coloroffset + (1-exp_factor)*10 .. " g" rule_bad.width = 0.5*line.width -- we need two rules on each line! @@ -643,7 +782,7 @@ colorstretch = function (head) glue_ratio_output = {} for s in string.utfvalues(math.abs(glue_ratio)) do -- using math.abs here gets us rid of the minus sign local char = unicode.utf8.char(s) - glue_ratio_output[j] = nodenew(37,1) + glue_ratio_output[j] = nodenew(GLYPH,1) glue_ratio_output[j].font = font.current() glue_ratio_output[j].char = s j = j+1 diff --git a/Master/texmf-dist/tex/luatex/chickenize/chickenize.sty b/Master/texmf-dist/tex/luatex/chickenize/chickenize.sty index fc58953a20d..0e9a58626ce 100644 --- a/Master/texmf-dist/tex/luatex/chickenize/chickenize.sty +++ b/Master/texmf-dist/tex/luatex/chickenize/chickenize.sty @@ -8,13 +8,14 @@ %% %% EXPERIMENTAL CODE %% -%% This package is copyright © 2013 Arno L. Trautmann. It may be distributed and/or +%% This package is copyright © 2015 Arno L. Trautmann. It may be distributed and/or %% modified under the conditions of the LaTeX Project Public License, either version 1.3c %% of this license or (at your option) any later version. This work has the LPPL mainten- %% ance status ‘maintained’. \ProvidesPackage{chickenize}% - [2013/08/22 v0.2.1a chickenize package] + [2015/12/26 v0.2.2 chickenize package] \input{chickenize} + \iffalse \DeclareDocumentCommand\includegraphics{O{}m}{ \fbox{Chicken} %% actually, I'd love to draw an MP graph showing a chicken … diff --git a/Master/texmf-dist/tex/luatex/chickenize/chickenize.tex b/Master/texmf-dist/tex/luatex/chickenize/chickenize.tex index 955102e8a41..185c8e6326e 100644 --- a/Master/texmf-dist/tex/luatex/chickenize/chickenize.tex +++ b/Master/texmf-dist/tex/luatex/chickenize/chickenize.tex @@ -8,25 +8,46 @@ %% %% EXPERIMENTAL CODE %% -%% This package is copyright © 2013 Arno L. Trautmann. It may be distributed and/or +%% This package is copyright © 2015 Arno L. Trautmann. It may be distributed and/or %% modified under the conditions of the LaTeX Project Public License, either version 1.3c %% of this license or (at your option) any later version. This work has the LPPL mainten- %% ance status ‘maintained’. -\input{luatexbase.sty} \directlua{dofile(kpse.find_file("chickenize.lua"))} +\def\ALT{% + \bgroup% + \fontspec{Latin Modern Sans}% + A% + \kern-.37em \raisebox{.7ex}{\scalebox{0.25}{L}}% + \kern-.0em \raisebox{-0.98ex}{T}% + \egroup% +} + +\def\allownumberincommands{ + \catcode`\0=11 + \catcode`\1=11 + \catcode`\2=11 + \catcode`\3=11 + \catcode`\4=11 + \catcode`\5=11 + \catcode`\6=11 + \catcode`\7=11 + \catcode`\8=11 + \catcode`\9=11 +} + \def\BEClerize{ \chickenize \directlua{ - chickenstring[1] = "noise noise" - chickenstring[2] = "atom noise" - chickenstring[3] = "shot noise" - chickenstring[4] = "photon noise" - chickenstring[5] = "camera noise" - chickenstring[6] = "noising noise" - chickenstring[7] = "thermal noise" - chickenstring[8] = "electronic noise" - chickenstring[9] = "spin noise" + chickenstring[1] = "noise noise" + chickenstring[2] = "atom noise" + chickenstring[3] = "shot noise" + chickenstring[4] = "photon noise" + chickenstring[5] = "camera noise" + chickenstring[6] = "noising noise" + chickenstring[7] = "thermal noise" + chickenstring[8] = "electronic noise" + chickenstring[9] = "spin noise" chickenstring[10] = "electron noise" chickenstring[11] = "Bogoliubov noise" chickenstring[12] = "white noise" @@ -53,6 +74,11 @@ \def\unboustrophedoninverse{ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","boustrophedon_inverse")}} +\def\bubblesort{ + \directlua{luatexbase.add_to_callback("post_linebreak_filter",bubblesort,"bubblesort")}} +\def\unbubblesort{ + \directlua{luatexbase.remove_from_callback("bubblesort","bubblesort")}} + \def\chickenize{ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",chickenize,"chickenize") luatexbase.add_to_callback("start_page_number", @@ -78,7 +104,12 @@ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","stretch_expansion")}} \def\countglyphs{ - \directlua{glyphnumber = 0 spacenumber = 0 + \directlua{ + counted_glyphs_by_code = {} + for i = 1,10000 do + counted_glyphs_by_code[i] = 0 + end + glyphnumber = 0 spacenumber = 0 luatexbase.add_to_callback("post_linebreak_filter",countglyphs,"countglyphs") luatexbase.add_to_callback("stop_run",printglyphnumber,"printglyphnumber") } @@ -168,6 +199,19 @@ \def\unleetspeak{ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","1337")}} +\def\leftsideright#1{ + \directlua{luatexbase.add_to_callback("pre_linebreak_filter",leftsideright,"leftsideright")} + \directlua{ + leftsiderightindex = {#1} + leftsiderightarray = {} + for _,i in pairs(leftsiderightindex) do + leftsiderightarray[i] = true + end + } +} +\def\unleftsideright{ + \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","leftsideright")}} + \def\letterspaceadjust{ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",letterspaceadjust,"letterspaceadjust")}} \def\unletterspaceadjust{ @@ -187,13 +231,18 @@ \def\matrixize{ \directlua{luatexbase.add_to_callback("pre_linebreak_filter",matrixize,"matrixize")}} \def\unmatrixize{ - \directlua{luatexbase.remove_from_callback("pre_linebreak_filter",matrixize)}} + \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","matrixize")}} \def\milkcow{ %% FIXME %% to be implemented \directlua{}} \def\unmilkcow{ \directlua{}} +\def\medievalumlaut{ + \directlua{luatexbase.add_to_callback("post_linebreak_filter",medievalumlaut,"medievalumlaut")}} +\def\unmedievalumlaut{ + \directlua{luatexbase.remove_from_callback("post_linebreak_filter","medievalumlaut")}} + \def\pancakenize{ \directlua{luatexbase.add_to_callback("stop_run",pancaketext,"pancaketext")}} @@ -203,8 +252,8 @@ \def\unrainbowcolor{ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","rainbowcolor") rainbowcolor = false}} - \let\nyanize\rainbowcolor - \let\unnyanize\unrainbowcolor +\let\nyanize\rainbowcolor +\let\unnyanize\unrainbowcolor \def\randomcolor{ \directlua{luatexbase.add_to_callback("post_linebreak_filter",randomcolor,"randomcolor")}} @@ -248,16 +297,42 @@ \directlua{addtosubstitutions("#1","#2")} } +\def\suppressonecharbreak{ + \directlua{luatexbase.add_to_callback("pre_linebreak_filter",suppressonecharbreak,"suppressonecharbreak")}} +\def\unsuppressonecharbreak{ + \directlua{luatexbase.remove_from_callback("pre_linebreak_filter","suppressonecharbreak")}} + \def\tabularasa{ \directlua{luatexbase.add_to_callback("post_linebreak_filter",tabularasa,"tabularasa")}} \def\untabularasa{ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","tabularasa")}} +\def\tanjanize{ + \directlua{luatexbase.add_to_callback("post_linebreak_filter",tanjanize,"tanjanize")}} +\def\untanjanize{ + \directlua{luatexbase.remove_from_callback("post_linebreak_filter","tanjanize")}} + \def\uppercasecolor{ \directlua{luatexbase.add_to_callback("post_linebreak_filter",uppercasecolor,"uppercasecolor")}} \def\unuppercasecolor{ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","uppercasecolor")}} +\def\upsidedown#1{ + \directlua{luatexbase.add_to_callback("post_linebreak_filter",upsidedown,"upsidedown")} + \directlua{ + upsidedownindex = {#1} + upsidedownarray = {} + for _,i in pairs(upsidedownindex) do + upsidedownarray[i] = true + end + } +} +\def\unupsidedown{ + \directlua{luatexbase.remove_from_callback("post_linebreak_filter","upsidedown")}} + +\def\unuppercasecolor{ + \directlua{luatexbase.remove_from_callback("post_linebreak_filter","upsidedow")}} + \def\variantjustification{ \directlua{luatexbase.add_to_callback("post_linebreak_filter",variantjustification,"variantjustification")}} \def\unvariantjustification{ @@ -267,13 +342,13 @@ \directlua{luatexbase.add_to_callback("post_linebreak_filter",zebranize,"zebranize")}} \def\unzebranize{ \directlua{luatexbase.remove_from_callback("post_linebreak_filter","zebranize")}} -\newluatexattribute\leetattr -\newluatexattribute\letterspaceadjustattr -\newluatexattribute\randcolorattr -\newluatexattribute\randfontsattr -\newluatexattribute\randuclcattr -\newluatexattribute\tabularasaattr -\newluatexattribute\uppercasecolorattr +\newattribute\leetattr +\newattribute\letterspaceadjustattr +\newattribute\randcolorattr +\newattribute\randfontsattr +\newattribute\randuclcattr +\newattribute\tabularasaattr +\newattribute\uppercasecolorattr \long\def\textleetspeak#1% {\setluatexattribute\leetattr{42}#1\unsetluatexattribute\leetattr} |