diff options
Diffstat (limited to 'macros/luatex/generic/chickenize/chickenize.lua')
-rw-r--r-- | macros/luatex/generic/chickenize/chickenize.lua | 965 |
1 files changed, 0 insertions, 965 deletions
diff --git a/macros/luatex/generic/chickenize/chickenize.lua b/macros/luatex/generic/chickenize/chickenize.lua deleted file mode 100644 index c25aa75b75..0000000000 --- a/macros/luatex/generic/chickenize/chickenize.lua +++ /dev/null @@ -1,965 +0,0 @@ --- --- This is file `chickenize.lua', --- generated with the docstrip utility. --- --- The original source files were: --- --- chickenize.dtx (with options: `lua') --- --- EXPERIMENTAL CODE --- --- This package is copyright © 2017 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’. - -local nodeid = node.id -local nodecopy = node.copy -local nodenew = node.new -local nodetail = node.tail -local nodeslide = node.slide -local noderemove = node.remove -local nodetraverseid = node.traverse_id -local nodeinsertafter = node.insert_after -local nodeinsertbefore = node.insert_before - -Hhead = nodeid("hhead") -RULE = nodeid("rule") -GLUE = nodeid("glue") -WHAT = nodeid("whatsit") -COL = node.subtype("pdf_colorstack") -DISC = nodeid("disc") -GLYPH = nodeid("glyph") -GLUE = nodeid("glue") -HLIST = nodeid("hlist") -KERN = nodeid("kern") -PUNCT = nodeid("punct") -PENALTY = nodeid("penalty") -PDF_LITERAL = node.subtype("pdf_literal") -color_push = nodenew(WHAT,COL) -color_pop = nodenew(WHAT,COL) -color_push.stack = 0 -color_pop.stack = 0 -color_push.command = 1 -color_pop.command = 2 -chicken_pagenumbers = true - -chickenstring = {} -chickenstring[1] = "chicken" -- chickenstring is a table, please remeber this! - -chickenizefraction = 0.5 --- set this to a small value to fool somebody, or to see if your text has been read carefully. This is also a great way to lay easter eggs for your own class / package … -chicken_substitutions = 0 -- value to count the substituted chickens. Makes sense for testing your proofreaders. - -local match = unicode.utf8.match -chickenize_ignore_word = false -chickenize_real_stuff = function(i,head) - while ((i.next.id == GLYPH) or (i.next.id == KERN) or (i.next.id == DISC) or (i.next.id == HLIST)) do --find end of a word - i.next = i.next.next - end - - chicken = {} -- constructing the node list. - --- Should this be done only once? No, otherwise we lose the freedom to change the string in-document. --- 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(GLYPH,1) -- only a dummy for the loop - for i = 1,string.len(chickenstring_tmp) do - chicken[i] = nodenew(GLYPH,1) - chicken[i].font = font.current() - chicken[i-1].next = chicken[i] - end - - j = 1 - for s in string.utfvalues(chickenstring_tmp) do - local char = unicode.utf8.char(s) - chicken[j].char = s - if match(char,"%s") then - chicken[j] = nodenew(GLUE) - chicken[j].width = space - chicken[j].shrink = shrink - chicken[j].stretch = stretch - end - j = j+1 - end - - nodeslide(chicken[1]) - lang.hyphenate(chicken[1]) - chicken[1] = node.kerning(chicken[1]) -- FIXME: does not work - chicken[1] = node.ligaturing(chicken[1]) -- dito - - nodeinsertbefore(head,i,chicken[1]) - chicken[1].next = chicken[2] -- seems to be necessary … to be fixed - chicken[string.len(chickenstring_tmp)].next = i.next - - -- shift lowercase latin letter to uppercase if the original input was an uppercase - if (chickenize_capital and (chicken[1].char > 96 and chicken[1].char < 123)) then - chicken[1].char = chicken[1].char - 32 - end - - return head -end - -chickenize = function(head) - 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 == GLYPH) or (i.next.id == DISC) or (i.next.id == PUNCT) or (i.next.id == KERN)) then - chickenize_ignore_word = false - end - end - return head -end - -local separator = string.rep("=", 28) -local texiowrite_nl = texio.write_nl -nicetext = function() - texiowrite_nl("Output written on "..tex.jobname..".pdf ("..status.total_pages.." chicken,".." eggs).") - texiowrite_nl(" ") - texiowrite_nl(separator) - texiowrite_nl("Hello my dear user,") - texiowrite_nl("good job, now go outside and enjoy the world!") - texiowrite_nl(" ") - texiowrite_nl("And don't forget to feed your chicken!") - texiowrite_nl(separator .. "\n") - if chickencount then - texiowrite_nl("There were "..chicken_substitutions.." substitutions made.") - texiowrite_nl(separator) - end -end -boustrophedon = function(head) - rot = node.new(WHAT,PDF_LITERAL) - rot2 = node.new(WHAT,PDF_LITERAL) - odd = true - for line in node.traverse_id(0,head) do - if odd == false then - w = line.width/65536*0.99625 -- empirical correction factor (?) - rot.data = "-1 0 0 1 "..w.." 0 cm" - rot2.data = "-1 0 0 1 "..-w.." 0 cm" - line.head = node.insert_before(line.head,line.head,nodecopy(rot)) - nodeinsertafter(line.head,nodetail(line.head),nodecopy(rot2)) - odd = true - else - odd = false - end - end - return head -end -boustrophedon_glyphs = function(head) - odd = false - rot = nodenew(WHAT,PDF_LITERAL) - rot2 = nodenew(WHAT,PDF_LITERAL) - for line in nodetraverseid(0,head) do - if odd==true then - line.dir = "TRT" - 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" - line.head = node.insert_before(line.head,g,nodecopy(rot)) - nodeinsertafter(line.head,g,nodecopy(rot2)) - end - odd = false - else - line.dir = "TLT" - odd = true - end - end - return head -end -boustrophedon_inverse = function(head) - rot = node.new(WHAT,PDF_LITERAL) - rot2 = node.new(WHAT,PDF_LITERAL) - odd = true - for line in node.traverse_id(0,head) do - if odd == false then -texio.write_nl(line.height) - w = line.width/65536*0.99625 -- empirical correction factor (?) - h = line.height/65536*0.99625 - rot.data = "-1 0 0 -1 "..w.." "..h.." cm" - rot2.data = "-1 0 0 -1 "..-w.." "..0.5*h.." cm" - line.head = node.insert_before(line.head,line.head,node.copy(rot)) - node.insert_after(line.head,node.tail(line.head),node.copy(rot2)) - odd = true - else - odd = false - end - 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(GLYPH,line.head) do - glyphnumber = glyphnumber + 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 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(GLYPH,head) do - if (glyph.next.id == 10) then - wordnumber = wordnumber + 1 - end - end - wordnumber = wordnumber + 1 -- add 1 for the last word in a paragraph which is not found otherwise - return head -end -printwordnumber = function() - texiowrite_nl("\nNumber of words in this document: "..wordnumber) -end - -function detectdoublewords(head) - prevlastword = {} -- array of numbers representing the glyphs - prevfirstword = {} - newlastword = {} - newfirstword = {} - for line in nodetraverseid(0,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 - end -texio.write_nl("nfw:"..#newfirstword) - end -end - -function printdoublewords() - texio.write_nl("finished") -end -local quotestrings = { - [171] = true, [172] = true, - [8216] = true, [8217] = true, [8218] = true, - [8219] = true, [8220] = true, [8221] = true, - [8222] = true, [8223] = true, - [8248] = true, [8249] = true, [8250] = true, -} -guttenbergenize_rq = function(head) - for n in nodetraverseid(nodeid"glyph",head) do - local i = n.char - if quotestrings[i] then - noderemove(head,n) - end - end - return head -end -hammertimedelay = 1.2 -local htime_separator = string.rep("=", 30) .. "\n" -- slightly inconsistent with the “nicetext” -hammertime = function(head) - if hammerfirst then - texiowrite_nl(htime_separator) - texiowrite_nl("============STOP!=============\n") - texiowrite_nl(htime_separator .. "\n\n\n") - os.sleep (hammertimedelay*1.5) - texiowrite_nl(htime_separator .. "\n") - texiowrite_nl("==========HAMMERTIME==========\n") - texiowrite_nl(htime_separator .. "\n\n") - os.sleep (hammertimedelay) - hammerfirst = false - else - os.sleep (hammertimedelay) - texiowrite_nl(htime_separator) - texiowrite_nl("======U can't touch this!=====\n") - texiowrite_nl(htime_separator .. "\n\n") - os.sleep (hammertimedelay*0.5) - end - return head -end -itsame = function() -local mr = function(a,b) rectangle({a*10,b*-10},10,10) end -color = "1 .6 0" -for i = 6,9 do mr(i,3) end -for i = 3,11 do mr(i,4) end -for i = 3,12 do mr(i,5) end -for i = 4,8 do mr(i,6) end -for i = 4,10 do mr(i,7) end -for i = 1,12 do mr(i,11) end -for i = 1,12 do mr(i,12) end -for i = 1,12 do mr(i,13) end - -color = ".3 .5 .2" -for i = 3,5 do mr(i,3) end mr(8,3) -mr(2,4) mr(4,4) mr(8,4) -mr(2,5) mr(4,5) mr(5,5) mr(9,5) -mr(2,6) mr(3,6) for i = 8,11 do mr(i,6) end -for i = 3,8 do mr(i,8) end -for i = 2,11 do mr(i,9) end -for i = 1,12 do mr(i,10) end -mr(3,11) mr(10,11) -for i = 2,4 do mr(i,15) end for i = 9,11 do mr(i,15) end -for i = 1,4 do mr(i,16) end for i = 9,12 do mr(i,16) end - -color = "1 0 0" -for i = 4,9 do mr(i,1) end -for i = 3,12 do mr(i,2) end -for i = 8,10 do mr(5,i) end -for i = 5,8 do mr(i,10) end -mr(8,9) mr(4,11) mr(6,11) mr(7,11) mr(9,11) -for i = 4,9 do mr(i,12) end -for i = 3,10 do mr(i,13) end -for i = 3,5 do mr(i,14) end -for i = 7,10 do mr(i,14) end -end -chickenkernamount = 0 -chickeninvertkerning = false - -function kernmanipulate (head) - if chickeninvertkerning then -- invert the kerning - for n in nodetraverseid(11,head) do - n.kern = -n.kern - end - else -- if not, set it to the given value - for n in nodetraverseid(11,head) do - n.kern = chickenkernamount - end - end - return head -end - -leetspeak_onlytext = false -leettable = { - [101] = 51, -- E - [105] = 49, -- I - [108] = 49, -- L - [111] = 48, -- O - [115] = 53, -- S - [116] = 55, -- T - - [101-32] = 51, -- e - [105-32] = 49, -- i - [108-32] = 49, -- l - [111-32] = 48, -- o - [115-32] = 53, -- s - [116-32] = 55, -- t -} -leet = function(head) - for line in nodetraverseid(Hhead,head) do - for i in nodetraverseid(GLYPH,line.head) do - if not leetspeak_onlytext or - node.has_attribute(i,luatexbase.attributes.leetattr) - then - if leettable[i.char] then - i.char = leettable[i.char] - end - end - end - 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(WHAT,PDF_LITERAL) - shift2 = nodenew(WHAT,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_pen = nodenew(nodeid"penalty") - -letterspace_glue.width = tex.sp"0pt" -letterspace_glue.stretch = tex.sp"0.5pt" -letterspace_pen.penalty = 10000 -letterspaceadjust = function(head) - for glyph in nodetraverseid(nodeid"glyph", head) do - if glyph.prev and (glyph.prev.id == nodeid"glyph" or glyph.prev.id == nodeid"disc" or glyph.prev.id == nodeid"kern") then - local g = nodecopy(letterspace_glue) - nodeinsertbefore(head, glyph, g) - nodeinsertbefore(head, g, nodecopy(letterspace_pen)) - end - end - return head -end -textletterspaceadjust = function(head) - for glyph in nodetraverseid(nodeid"glyph", head) do - if node.has_attribute(glyph,luatexbase.attributes.letterspaceadjustattr) then - if glyph.prev and (glyph.prev.id == node.id"glyph" or glyph.prev.id == node.id"disc" or glyph.prev.id == nodeid"kern") then - local g = node.copy(letterspace_glue) - nodeinsertbefore(head, glyph, g) - nodeinsertbefore(head, g, nodecopy(letterspace_pen)) - end - end - end - luatexbase.remove_from_callback("pre_linebreak_filter","textletterspaceadjust") - return head -end -matrixize = function(head) - x = {} - s = nodenew(nodeid"disc") - for n in nodetraverseid(nodeid"glyph",head) do - j = n.char - for m = 0,7 do -- stay ASCII for now - x[7-m] = nodecopy(n) -- to get the same font etc. - - if (j / (2^(7-m)) < 1) then - x[7-m].char = 48 - else - x[7-m].char = 49 - j = j-(2^(7-m)) - end - nodeinsertbefore(head,n,x[7-m]) - nodeinsertafter(head,x[7-m],nodecopy(s)) - end - noderemove(head,n) - 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(WHAT,PDF_LITERAL) - shift2 = nodenew(WHAT,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(KERN) - 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() - texiowrite_nl("Output written on "..tex.jobname..".pdf ("..status.total_pages.." chicken,".." eggs).") - texiowrite_nl(" ") - texiowrite_nl(separator) - texiowrite_nl("Soo ... you decided to use \\pancakenize.") - texiowrite_nl("That means you owe me a pancake!") - texiowrite_nl(" ") - texiowrite_nl("(This goes by document, not compilation.)") - texiowrite_nl(separator.."\n\n") - texiowrite_nl("Looking forward for my pancake! :)") - texiowrite_nl("\n\n") -end - -randomfontslower = 1 -randomfontsupper = 0 -randomfonts = function(head) - local rfub - if randomfontsupper > 0 then -- fixme: this should be done only once, no? Or at every paragraph? - rfub = randomfontsupper -- user-specified value - else - rfub = font.max() -- or just take all fonts - end - for line in nodetraverseid(Hhead,head) do - for i in nodetraverseid(GLYPH,line.head) do - if not(randomfonts_onlytext) or node.has_attribute(i,luatexbase.attributes.randfontsattr) then - i.font = math.random(randomfontslower,rfub) - end - end - end - return head -end -uclcratio = 0.5 -- ratio between uppercase and lower case -randomuclc = function(head) - 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] - else - i.char = tex.lccode[i.char] - end - end - end - return head -end -randomchars = function(head) - for line in nodetraverseid(Hhead,head) do - for i in nodetraverseid(GLYPH,line.head) do - i.char = math.floor(math.random()*512) - end - end - return head -end -randomcolor_grey = false -randomcolor_onlytext = false --switch between local and global colorization -rainbowcolor = false - -grey_lower = 0 -grey_upper = 900 - -Rgb_lower = 1 -rGb_lower = 1 -rgB_lower = 1 -Rgb_upper = 254 -rGb_upper = 254 -rgB_upper = 254 -rainbow_step = 0.005 -rainbow_Rgb = 1-rainbow_step -- we start in the red phase -rainbow_rGb = rainbow_step -- values x must always be 0 < x < 1 -rainbow_rgB = rainbow_step -rainind = 1 -- 1:red,2:yellow,3:green,4:blue,5:purple -randomcolorstring = function() - if randomcolor_grey then - return (0.001*math.random(grey_lower,grey_upper)).." g" - elseif rainbowcolor then - if rainind == 1 then -- red - rainbow_rGb = rainbow_rGb + rainbow_step - if rainbow_rGb >= 1-rainbow_step then rainind = 2 end - elseif rainind == 2 then -- yellow - rainbow_Rgb = rainbow_Rgb - rainbow_step - if rainbow_Rgb <= rainbow_step then rainind = 3 end - elseif rainind == 3 then -- green - rainbow_rgB = rainbow_rgB + rainbow_step - rainbow_rGb = rainbow_rGb - rainbow_step - if rainbow_rGb <= rainbow_step then rainind = 4 end - elseif rainind == 4 then -- blue - rainbow_Rgb = rainbow_Rgb + rainbow_step - if rainbow_Rgb >= 1-rainbow_step then rainind = 5 end - else -- purple - rainbow_rgB = rainbow_rgB - rainbow_step - if rainbow_rgB <= rainbow_step then rainind = 1 end - end - return rainbow_Rgb.." "..rainbow_rGb.." "..rainbow_rgB.." rg" - else - Rgb = math.random(Rgb_lower,Rgb_upper)/255 - rGb = math.random(rGb_lower,rGb_upper)/255 - rgB = math.random(rgB_lower,rgB_upper)/255 - return Rgb.." "..rGb.." "..rgB.." ".." rg" - end -end -randomcolor = function(head) - for line in nodetraverseid(0,head) do - for i in nodetraverseid(GLYPH,line.head) do - if not(randomcolor_onlytext) or - (node.has_attribute(i,luatexbase.attributes.randcolorattr)) - then - color_push.data = randomcolorstring() -- color or grey string - line.head = nodeinsertbefore(line.head,i,nodecopy(color_push)) - nodeinsertafter(line.head,i,nodecopy(color_pop)) - end - end - end - return head -end -substitutewords_strings = {} - -addtosubstitutions = function(input,output) - substitutewords_strings[#substitutewords_strings + 1] = {} - substitutewords_strings[#substitutewords_strings][1] = input - substitutewords_strings[#substitutewords_strings][2] = output -end - -substitutewords = function(head) - for i = 1,#substitutewords_strings do - head = string.gsub(head,substitutewords_strings[i][1],substitutewords_strings[i][2]) - end - return head -end -suppressonecharbreakpenaltynode = node.new(PENALTY) -suppressonecharbreakpenaltynode.penalty = 10000 -function suppressonecharbreak(head) - for i in node.traverse_id(GLUE,head) do - if ((i.next) and (i.next.next.id == GLUE)) then - pen = node.copy(suppressonecharbreakpenaltynode) - node.insert_after(head,i.next,pen) - end - end - - return head -end -tabularasa_onlytext = false - -tabularasa = function(head) - local s = nodenew(nodeid"kern") - for line in nodetraverseid(nodeid"hlist",head) do - for n in nodetraverseid(nodeid"glyph",line.head) do - if not(tabularasa_onlytext) or node.has_attribute(n,luatexbase.attributes.tabularasaattr) then - s.kern = n.width - nodeinsertafter(line.list,n,nodecopy(s)) - line.head = noderemove(line.list,n) - end - end - end - return head -end -tanjanize = function(head) - local s = nodenew(nodeid"kern") - local m = nodenew(GLYPH,1) - local use_letter_i = true - scale = nodenew(WHAT,PDF_LITERAL) - scale2 = nodenew(WHAT,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) - for line in nodetraverseid(Hhead,head) do - for upper in nodetraverseid(GLYPH,line.head) do - if not(uppercasecolor_onlytext) or node.has_attribute(upper,luatexbase.attributes.uppercasecolorattr) then - if (((upper.char > 64) and (upper.char < 91)) or - ((upper.char > 57424) and (upper.char < 57451))) then -- for small caps! nice ☺ - color_push.data = randomcolorstring() -- color or grey string - line.head = nodeinsertbefore(line.head,upper,nodecopy(color_push)) - nodeinsertafter(line.head,upper,nodecopy(color_pop)) - end - end - end - 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(WHAT,PDF_LITERAL) - shift2 = nodenew(WHAT,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 - -colorstretch_coloroffset = 0.5 -colorstretch_colorrange = 0.5 -chickenize_rule_bad_height = 4/5 -- height and depth of the rules -chickenize_rule_bad_depth = 1/5 - -colorstretchnumbers = true -drawstretchthreshold = 0.1 -drawexpansionthreshold = 0.9 -colorstretch = function (head) - local f = font.getfont(font.current()).characters - for line in nodetraverseid(Hhead,head) do - local rule_bad = nodenew(RULE) - - if colorexpansion then -- if also the font expansion should be shown - local g = line.head - 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! - end - else - rule_bad.width = line.width -- only the space expansion should be shown, only one rule - end - rule_bad.height = tex.baselineskip.width*chickenize_rule_bad_height -- this should give a better output - rule_bad.depth = tex.baselineskip.width*chickenize_rule_bad_depth - - local glue_ratio = 0 - if line.glue_order == 0 then - if line.glue_sign == 1 then - glue_ratio = colorstretch_colorrange * math.min(line.glue_set,1) - else - glue_ratio = -colorstretch_colorrange * math.min(line.glue_set,1) - end - end - color_push.data = colorstretch_coloroffset + glue_ratio .. " g" - --- set up output - local p = line.head - - -- a rule to immitate kerning all the way back - local kern_back = nodenew(RULE) - kern_back.width = -line.width - - -- if the text should still be displayed, the color and box nodes are inserted additionally - -- and the head is set to the color node - if keeptext then - line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push)) - else - node.flush_list(p) - line.head = nodecopy(color_push) - end - nodeinsertafter(line.head,line.head,rule_bad) -- then the rule - nodeinsertafter(line.head,line.head.next,nodecopy(color_pop)) -- and then pop! - tmpnode = nodeinsertafter(line.head,line.head.next.next,kern_back) - - -- then a rule with the expansion color - if colorexpansion then -- if also the stretch/shrink of letters should be shown - color_push.data = exp_color - nodeinsertafter(line.head,tmpnode,nodecopy(color_push)) - nodeinsertafter(line.head,tmpnode.next,nodecopy(rule_bad)) - nodeinsertafter(line.head,tmpnode.next.next,nodecopy(color_pop)) - end - if colorstretchnumbers then - j = 1 - 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(GLYPH,1) - glue_ratio_output[j].font = font.current() - glue_ratio_output[j].char = s - j = j+1 - end - if math.abs(glue_ratio) > drawstretchthreshold then - if glue_ratio < 0 then color_push.data = "0.99 0 0 rg" - else color_push.data = "0 0.99 0 rg" end - else color_push.data = "0 0 0 rg" - end - - nodeinsertafter(line.head,node.tail(line.head),nodecopy(color_push)) - for i = 1,math.min(j-1,7) do - nodeinsertafter(line.head,node.tail(line.head),glue_ratio_output[i]) - end - nodeinsertafter(line.head,node.tail(line.head),nodecopy(color_pop)) - end -- end of stretch number insertion - end - return head -end - -function scorpionize_color(head) - color_push.data = ".35 .55 .75 rg" - nodeinsertafter(head,head,nodecopy(color_push)) - nodeinsertafter(head,node.tail(head),nodecopy(color_pop)) - return head -end -substlist = {} -substlist[1488] = 64289 -substlist[1491] = 64290 -substlist[1492] = 64291 -substlist[1499] = 64292 -substlist[1500] = 64293 -substlist[1501] = 64294 -substlist[1512] = 64295 -substlist[1514] = 64296 -function variantjustification(head) - math.randomseed(1) - for line in nodetraverseid(nodeid"hhead",head) do - if (line.glue_sign == 1 and line.glue_order == 0) then -- exclude the last line! - substitutions_wide = {} -- we store all “expandable” letters of each line - for n in nodetraverseid(nodeid"glyph",line.head) do - if (substlist[n.char]) then - substitutions_wide[#substitutions_wide+1] = n - end - end - line.glue_set = 0 -- deactivate normal glue expansion - local width = node.dimensions(line.head) -- check the new width of the line - local goal = line.width - while (width < goal and #substitutions_wide > 0) do - x = math.random(#substitutions_wide) -- choose randomly a glyph to be substituted - oldchar = substitutions_wide[x].char - substitutions_wide[x].char = substlist[substitutions_wide[x].char] -- substitute by wide letter - width = node.dimensions(line.head) -- check if the line is too wide - if width > goal then substitutions_wide[x].char = oldchar break end -- substitute back if the line would be too wide and break out of the loop - table.remove(substitutions_wide,x) -- if further substitutions have to be done, remove the just substituted node from the list - end - end - end - return head -end -zebracolorarray = {} -zebracolorarray_bg = {} -zebracolorarray[1] = "0.1 g" -zebracolorarray[2] = "0.9 g" -zebracolorarray_bg[1] = "0.9 g" -zebracolorarray_bg[2] = "0.1 g" -function zebranize(head) - zebracolor = 1 - for line in nodetraverseid(nodeid"hhead",head) do - if zebracolor == #zebracolorarray then zebracolor = 0 end - zebracolor = zebracolor + 1 - color_push.data = zebracolorarray[zebracolor] - line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push)) - for n in nodetraverseid(nodeid"glyph",line.head) do - if n.next then else - nodeinsertafter(line.head,n,nodecopy(color_pull)) - end - end - - local rule_zebra = nodenew(RULE) - rule_zebra.width = line.width - rule_zebra.height = tex.baselineskip.width*4/5 - rule_zebra.depth = tex.baselineskip.width*1/5 - - local kern_back = nodenew(RULE) - kern_back.width = -line.width - - color_push.data = zebracolorarray_bg[zebracolor] - line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_pop)) - line.head = nodeinsertbefore(line.head,line.head,nodecopy(color_push)) - nodeinsertafter(line.head,line.head,kern_back) - nodeinsertafter(line.head,line.head,rule_zebra) - end - return (head) -end --- -function pdf_print (...) - for _, str in ipairs({...}) do - pdf.print(str .. " ") - end - pdf.print("\n") -end - -function move (p) - pdf_print(p[1],p[2],"m") -end - -function line (p) - pdf_print(p[1],p[2],"l") -end - -function curve(p1,p2,p3) - pdf_print(p1[1], p1[2], - p2[1], p2[2], - p3[1], p3[2], "c") -end - -function close () - pdf_print("h") -end - -function linewidth (w) - pdf_print(w,"w") -end - -function stroke () - pdf_print("S") -end --- - -function strictcircle(center,radius) - local left = {center[1] - radius, center[2]} - local lefttop = {left[1], left[2] + 1.45*radius} - local leftbot = {left[1], left[2] - 1.45*radius} - local right = {center[1] + radius, center[2]} - local righttop = {right[1], right[2] + 1.45*radius} - local rightbot = {right[1], right[2] - 1.45*radius} - - move (left) - curve (lefttop, righttop, right) - curve (rightbot, leftbot, left) -stroke() -end - -function disturb_point(point) - return {point[1] + math.random()*5 - 2.5, - point[2] + math.random()*5 - 2.5} -end - -function sloppycircle(center,radius) - local left = disturb_point({center[1] - radius, center[2]}) - local lefttop = disturb_point({left[1], left[2] + 1.45*radius}) - local leftbot = {lefttop[1], lefttop[2] - 2.9*radius} - local right = disturb_point({center[1] + radius, center[2]}) - local righttop = disturb_point({right[1], right[2] + 1.45*radius}) - local rightbot = disturb_point({right[1], right[2] - 1.45*radius}) - - local right_end = disturb_point(right) - - move (right) - curve (rightbot, leftbot, left) - curve (lefttop, righttop, right_end) - linewidth(math.random()+0.5) - stroke() -end - -function sloppyline(start,stop) - local start_line = disturb_point(start) - local stop_line = disturb_point(stop) - start = disturb_point(start) - stop = disturb_point(stop) - move(start) curve(start_line,stop_line,stop) - linewidth(math.random()+0.5) - stroke() -end --- --- End of File `chickenize.lua'. |