diff options
author | Karl Berry <karl@freefriends.org> | 2015-03-13 23:23:22 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2015-03-13 23:23:22 +0000 |
commit | 3e4facabd7e33e78ece63d391d6fc6c94842873d (patch) | |
tree | 6774944cbbd3246b1f8bf37f20927ad03355ada8 /Master/texmf-dist/tex | |
parent | 92c0eccd62a3eb57e56ee44400ebe63fec446bf6 (diff) |
luatodonotes (13mar15)
git-svn-id: svn://tug.org/texlive/trunk@36505 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r-- | Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.lua | 447 | ||||
-rw-r--r-- | Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.sty | 101 |
2 files changed, 288 insertions, 260 deletions
diff --git a/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.lua b/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.lua index 61175bbbf68..f84fc9415de 100644 --- a/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.lua +++ b/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.lua @@ -1,6 +1,6 @@ -- --- Copyright (C) 2014 by Fabian Lipp <fabian.lipp@gmx.de> --- ------------------------------------------------------- +-- Copyright (C) 2014-2015 by Fabian Lipp <fabian.lipp@gmx.de> +-- ------------------------------------------------------------ -- -- This file may be distributed and/or modified under the -- conditions of the LaTeX Project Public License, either version 1.2 @@ -21,7 +21,7 @@ local point = require'path_point' local pathLine = require'path_line' --local bezier3 = require'path_bezier3' --- TODO Funktionen/Variablen in Namespace o. Ä. packen +luatodonotes = {} -- strings used to switch to standard catcodes for LaTeX packages local catcodeStart = "\\makeatletter" @@ -40,16 +40,57 @@ local const1In = string.todimen("1in") -- needed for calculations of page border -- + distanceNotesPageBorder (distance from the page borders to the outmost point -- of the labels) -- + distanceNotesText (horizontal distance between the labels and the text area) +-- + rasterHeight (height of raster for po leader algorithm) -- + todonotesDebug (activate debug outputs when true) +-- +-- values are filled into local variables in function initTodonotes (from +-- corresponding fields luatodonotes.*) +local noteInnerSep = nil +local noteInterSpace = nil +local routingAreaWidth = nil +local minNoteWidth = nil +local distanceNotesPageBorder = nil +local distanceNotesText = nil +local rasterHeight = nil +local todonotesDebug = nil -- stores information about available algorithms -positioningAlgos = {} -splittingAlgos = {} -leaderTypes = {} +local positioningAlgos = {} +local splittingAlgos = {} +local leaderTypes = {} + +local positioning = nil +local splitting = nil +local leaderType = nil +function luatodonotes.setPositioningAlgo(algo) + if positioningAlgos[algo] ~= nil then + positioning = positioningAlgos[algo] + else + positioning = positioningAlgos["inputOrderStacks"] + tex.print("\\PackageWarningNoLine{luatodonotes}{Invalid value for parameter positioning: " .. algo .. "}") + end +end +function luatodonotes.setSplittingAlgo(algo) + if splittingAlgos[algo] ~= nil then + splitting = splittingAlgos[algo] + else + splitting = splittingAlgos["none"] + tex.print("\\PackageWarningNoLine{luatodonotes}{Invalid value for parameter split: " .. algo .. "}") + end +end +function luatodonotes.setLeaderType(typ) + if leaderTypes[typ] ~= nil then + leaderType = leaderTypes[typ] + else + leaderType = leaderTypes["opo"] + tex.print("\\PackageWarningNoLine{luatodonotes}{Invalid value for parameter leadertype: " .. typ .. "}") + end +end -- stores the notes for the current page -notesForPage = {} +luatodonotes.notesForPage = {} +local notesForPage = luatodonotes.notesForPage -- Fields for each note: -- index: numbers notes in whole document -- indexOnPage: index of the note in the notesForPage array @@ -71,6 +112,7 @@ notesForPage = {} -- backgroundColor: color of background of note -- borderColor: color of border of note -- leaderWidth: width of leader (used as argument for tikz line width) +-- sizeCommand: fontsize command given as parameter for this note -- -- Additional fields for text area: -- noteType: constant string "area" @@ -149,7 +191,7 @@ function noteMt:boxForNoteText(rightSide) noteWidth = area.noteWidth - 2*noteInnerSep end local retval = "\\directlua{tex.box[\"@todonotes@notetextbox\"] = " .. - "node.copy_list(notesForPage[" .. self.indexOnPage .. "].textbox)}" + "node.copy_list(luatodonotes.notesForPage[" .. self.indexOnPage .. "].textbox)}" retval = retval .. "\\parbox{" .. noteWidth .. "sp}" .. "{\\raggedright\\unhbox\\@todonotes@notetextbox}" return retval @@ -229,10 +271,37 @@ end +-- divides notes in two lists (for left and right side) +-- side must be stored in note.rightSide for every note before using this function +local function segmentNotes(notes) + local availableNotesLeft = {} + local availableNotesRight = {} + for k, v in pairs(notes) do + if v.rightSide == true then + table.insert(availableNotesRight, k) + else + table.insert(availableNotesLeft, k) + end + end + return availableNotesLeft, availableNotesRight +end + + + -- is called by the sty-file when all settings (algorithms etc.) are made -function initTodonotes() +function luatodonotes.initTodonotes() + -- fill local variables (defined at begin of file) with package options + noteInnerSep = luatodonotes.noteInnerSep + noteInterSpace = luatodonotes.noteInterSpace + routingAreaWidth = luatodonotes.routingAreaWidth + minNoteWidth = luatodonotes.minNoteWidth + distanceNotesPageBorder = luatodonotes.distanceNotesPageBorder + distanceNotesText = luatodonotes.distanceNotesText + rasterHeight = luatodonotes.rasterHeight + todonotesDebug = luatodonotes.todonotesDebug + if positioning.needLinePositions then - luatexbase.add_to_callback("post_linebreak_filter", callbackOutputLinePositions, "outputLinePositions") + luatexbase.add_to_callback("post_linebreak_filter", luatodonotes.callbackOutputLinePositions, "outputLinePositions") tex.print("\\@starttoc{lpo}") tex.print("\\directlua{lpoFileStream = \\the\\tf@lpo}") end @@ -240,7 +309,14 @@ end -- valid values for noteType: nil/"" (for point in text), "area" -function addNoteToList(index, drawLeader, noteType) +function luatodonotes.addNoteToList(index, drawLeader, noteType) + if next(notesForPage) ~= nil + and index == notesForPage[#notesForPage].index then + -- Index is the same as for the previous note. + -- This can happen when commands are read multiple times + -- => don't add anything to list in this case + return + end local newNote = {} newNote.index = index newNote.textbox = node.copy_list(tex.box["@todonotes@notetextbox"]) @@ -250,6 +326,7 @@ function addNoteToList(index, drawLeader, noteType) newNote.backgroundColor = tex.toks["@todonotes@toks@currentbackgroundcolor"] newNote.borderColor = tex.toks["@todonotes@toks@currentbordercolor"] newNote.leaderWidth = tex.toks["@todonotes@toks@currentleaderwidth"] + newNote.sizeCommand = tex.toks["@todonotes@toks@sizecommand"] newNote.drawLeader = drawLeader if noteType == "area" then newNote.noteType = "area" @@ -261,13 +338,14 @@ function addNoteToList(index, drawLeader, noteType) notesForPage[newNote.indexOnPage] = newNote end -function clearNotes() +function luatodonotes.clearNotes() -- delete the texts for the notes on this page from memory -- (garbage collection does not work for nodes) for _, v in pairs(notesForPage) do node.free(v.textbox) end - notesForPage = notesForNextPage + luatodonotes.notesForPage = notesForNextPage + notesForPage = luatodonotes.notesForPage -- update indexOnPage for the new notes for k, v in pairs(notesForPage) do v.indexOnPage = k @@ -276,7 +354,7 @@ function clearNotes() currentPage = currentPage + 1 end -function processLastLineInTodoArea() +function luatodonotes.processLastLineInTodoArea() -- LaTeX counter is accessed as TeX count by prefixing c@ ind = tex.count["c@@todonotes@numberoftodonotes"] val = tex.count["c@@todonotes@numberofLinesInArea"] @@ -285,35 +363,19 @@ end -- *** constructing the linePositions list *** -function linePositionsNextPage() +function luatodonotes.linePositionsNextPage() linePositionsPageNr = linePositionsPageNr + 1 linePositionsCurPage = {} linePositions[linePositionsPageNr] = linePositionsCurPage end -function linePositionsAddLine(ycoord, lineheight, linedepth) +function luatodonotes.linePositionsAddLine(ycoord, lineheight, linedepth) local baseline = ycoord - tex.pageheight linePositionsCurPage[#linePositionsCurPage + 1] = {baseline, baseline + lineheight, baseline - linedepth} end --- DEBUG -function markLines() - print("marking lines for page " .. currentPage) - if linePositions[currentPage] ~= nil then - for _, v in pairs(linePositions[currentPage]) do - --local yPos = - (tex.pageheight - v[1]) - local yPos = v[3] - local yTop = v[2] - tex.print("\\draw[red] (10cm," .. yPos .."sp) circle(3pt);") - tex.print("\\fill[red] (10cm," .. yPos .."sp) circle(1pt);") - tex.print("\\draw[green] (2cm," .. yTop .."sp) -- ++(17cm,0);") - tex.print("\\draw[blue] (2cm," .. yPos .."sp) -- ++(17cm,0);") - end - end -end - -function getInputCoordinatesForNotes() +function luatodonotes.getInputCoordinatesForNotes() tex.sprint(catcodeStart) for k, v in ipairs(notesForPage) do local nodename = "@todonotes@" .. v.index .. " inText" @@ -322,9 +384,9 @@ function getInputCoordinatesForNotes() nodename .. "}{center}}") tex.sprint("\\pgfextracty{\\@todonotes@extracty}{\\pgfpointanchor{" .. nodename .. "}{center}}") - tex.print("\\directlua{notesForPage[" .. k .. "].origInputX = " .. + tex.print("\\directlua{luatodonotes.notesForPage[" .. k .. "].origInputX = " .. "tex.dimen[\"@todonotes@extractx\"]}") - tex.print("\\directlua{notesForPage[" .. k .. "].origInputY = " .. + tex.print("\\directlua{luatodonotes.notesForPage[" .. k .. "].origInputY = " .. "tex.dimen[\"@todonotes@extracty\"]}") if v.noteType == "area" then @@ -333,9 +395,9 @@ function getInputCoordinatesForNotes() nodename .. "}{center}}") tex.sprint("\\pgfextracty{\\@todonotes@extracty}{\\pgfpointanchor{" .. nodename .. "}{center}}") - tex.print("\\directlua{notesForPage[" .. k .. "].origInputEndX = " .. + tex.print("\\directlua{luatodonotes.notesForPage[" .. k .. "].origInputEndX = " .. "tex.dimen[\"@todonotes@extractx\"]}") - tex.print("\\directlua{notesForPage[" .. k .. "].origInputEndY = " .. + tex.print("\\directlua{luatodonotes.notesForPage[" .. k .. "].origInputEndY = " .. "tex.dimen[\"@todonotes@extracty\"]}") notesForPage[k].linesInArea = {} @@ -343,7 +405,7 @@ function getInputCoordinatesForNotes() nodename = "@todonotes@" .. v.index .. "@" .. i .. " areaSW" tex.sprint("\\pgfextracty{\\@todonotes@extracty}{\\pgfpointanchor{" .. nodename .. "}{center}}") - tex.print("\\directlua{notesForPage[" .. k .. "].linesInArea[" .. + tex.print("\\directlua{luatodonotes.notesForPage[" .. k .. "].linesInArea[" .. i .. "] = " .. "tex.dimen[\"@todonotes@extracty\"]}") end end @@ -351,7 +413,7 @@ function getInputCoordinatesForNotes() tex.sprint(catcodeEnd) end -function calcLabelAreaDimensions() +function luatodonotes.calcLabelAreaDimensions() local routingAreaSpace = 0 if leaderType.needRoutingArea then routingAreaSpace = routingAreaWidth @@ -394,7 +456,7 @@ function calcLabelAreaDimensions() labelArea.text = text end -function calcHeightsForNotes() +function luatodonotes.calcHeightsForNotes() -- function has to be called outside of a tikzpicture-environment tex.sprint(catcodeStart) for k, v in ipairs(notesForPage) do @@ -403,28 +465,28 @@ function calcHeightsForNotes() -- left side tex.sprint("\\savebox{\\@todonotes@heightcalcbox}" .. - "{" .. v:boxForNoteText(false) .. "}") + "{" .. v.sizeCommand .. v:boxForNoteText(false) .. "}") tex.sprint("\\@todonotes@heightcalcboxdepth=\\dp\\@todonotes@heightcalcbox") tex.sprint("\\@todonotes@heightcalcboxheight=\\ht\\@todonotes@heightcalcbox") - tex.sprint("\\directlua{notesForPage[" .. k .. "].heightLeft = " .. + tex.sprint("\\directlua{luatodonotes.notesForPage[" .. k .. "].heightLeft = " .. "tex.dimen[\"@todonotes@heightcalcboxheight\"]" .. " + tex.dimen[\"@todonotes@heightcalcboxdepth\"]}") -- right side tex.sprint("\\savebox{\\@todonotes@heightcalcbox}" .. - "{" .. v:boxForNoteText(true) .. "}") + "{" .. v.sizeCommand .. v:boxForNoteText(true) .. "}") tex.sprint("\\@todonotes@heightcalcboxdepth=\\dp\\@todonotes@heightcalcbox") tex.sprint("\\@todonotes@heightcalcboxheight=\\ht\\@todonotes@heightcalcbox") - tex.sprint("\\directlua{notesForPage[" .. k .. "].heightRight = " .. + tex.sprint("\\directlua{luatodonotes.notesForPage[" .. k .. "].heightRight = " .. "tex.dimen[\"@todonotes@heightcalcboxheight\"]" .. " + tex.dimen[\"@todonotes@heightcalcboxdepth\"]}") -- store pageNr for note -- (is determined as reference to a label) - tex.sprint("\\directlua{notesForPage[" .. k .. "].pageNr = " .. + tex.sprint("\\directlua{luatodonotes.notesForPage[" .. k .. "].pageNr = " .. "\\zref@extract{@todonotes@" .. v.index .. "}{abspage}}") if v.noteType == "area" then - tex.sprint("\\directlua{notesForPage[" .. k .. "].pageNrEnd = " .. + tex.sprint("\\directlua{luatodonotes.notesForPage[" .. k .. "].pageNrEnd = " .. "\\zref@extract{@todonotes@" .. v.index .. "@end}{abspage}}") end end @@ -432,7 +494,7 @@ function calcHeightsForNotes() end local inputShiftX = string.todimen("-0.05cm") -- sensible value depends on shape of mark -function printNotes() +function luatodonotes.printNotes() print("drawing labels for page " .. currentPage) -- seperate notes that should be placed on another page @@ -481,7 +543,7 @@ function printNotes() if todonotesDebug then local function outputWithPoints(val) if val ~= nil then - return val .. " (" .. number.topoints(val) .. ")" + return val .. " (" .. number.topoints(val, "%s%s") .. ")" else return "" end @@ -521,13 +583,15 @@ function printNotes() print("backgroundColor:" .. v.backgroundColor) print("borderColor: " .. v.borderColor) print("leaderWidth: " .. v.leaderWidth) + print("sizeCommand: " .. v.sizeCommand) print("drawLeader: " .. tostring(v.drawLeader)) end -- print note tex.print(catcodeStart) tex.print("\\node[@todonotes@notestyle,anchor=north west," .. - "fill=" .. v.backgroundColor .. ",draw=" .. v.borderColor .. "] " .. + "fill=" .. v.backgroundColor .. ",draw=" .. v.borderColor .. "," .. + "font=" .. v.sizeCommand .. "] " .. "(@todonotes@" .. v.index .. " note) at (" .. v.outputX .. "sp," .. v.outputY .. "sp) {" .. v:boxForNoteText(v.rightSide) .. "};") @@ -593,25 +657,25 @@ end -- * comparators for table.sort() * -- (yields true if first parameter should be placed before second parameter in -- sorted table) -function compareNoteInputXAsc(note1, note2) +local function compareNoteInputXAsc(note1, note2) if note1.inputX < note2.inputX then return true end end -function compareNoteIndInputXAsc(key1, key2) +local function compareNoteIndInputXAsc(key1, key2) if notesForPage[key1].inputX < notesForPage[key2].inputX then return true end end -function compareNoteIndInputXDesc(key1, key2) +local function compareNoteIndInputXDesc(key1, key2) if notesForPage[key1].inputX > notesForPage[key2].inputX then return true end end -function compareNoteIndInputYDesc(key1, key2) +local function compareNoteIndInputYDesc(key1, key2) local v1 = notesForPage[key1] local v2 = notesForPage[key2] if v1.inputY > v2.inputY then @@ -624,7 +688,7 @@ function compareNoteIndInputYDesc(key1, key2) end -- * callbacks for Luatex * -function appendStrToTokenlist(tokenlist, str) +local function appendStrToTokenlist(tokenlist, str) str:gsub(".", function(c) tokenlist[#tokenlist + 1] = {12, c:byte(), 0} end) @@ -633,9 +697,11 @@ end -- page to the output file (streamId is taken from lpoFileStream) at the -- beginning of every line -- should be called as post_linebreak_filter -function callbackOutputLinePositions(head) +local ID_GLYPH_NODE = node.id("glyph") +local ID_HLIST_NODE = node.id("hlist") +function luatodonotes.callbackOutputLinePositions(head) while head do - if head.id == 0 then -- id 0 is a hlist + if head.id == ID_HLIST_NODE then -- check if we are in the main text area (hlists in, e.g., -- tikz nodes should have other widths) if head.width == tex.dimen.textwidth then @@ -644,7 +710,7 @@ function callbackOutputLinePositions(head) local foundGlyph = false local glyphTest = head.head while glyphTest do - if glyphTest.id == 37 then -- glyph + if glyphTest.id == ID_GLYPH_NODE then foundGlyph = true break end @@ -709,7 +775,7 @@ end -- ********** Leader Drawing Algorithms ********** -function drawLeaderPath(note, path) +local function drawLeaderPath(note, path) if note.drawLeader == false then return end @@ -725,14 +791,14 @@ function drawLeaderPath(note, path) ",line width=" .. note.leaderWidth .. ",name path=leader] " .. path .. ";") if note.noteType == "area" then tex.print("\\path[name path=clipping] " .. clipPath .. ";") - tex.print("\\fill[@todonotes@leader,name intersections={of=leader and clipping, by=x,sort by=leader}] (x) circle(3pt);") + tex.print("\\fill[@todonotes@leader,name intersections={of=leader and clipping, by=x,sort by=leader},fill=" .. note.lineColor .. "] (x) circle(3pt);") tex.print("\\end{scope}") end end -- ** leader drawing: s-leaders -function drawSLeaders() +local function drawSLeaders() for k, v in ipairs(notesForPage) do drawLeaderPath(v, v:getLabelAnchorTikz() .. " -- " .. v:getInTextAnchorTikz()) @@ -743,14 +809,14 @@ leaderTypes["s"] = {algo = drawSLeaders} -- ** leader drawing: opo-leaders -function drawOpoLeader(v, opoShift, rightSide) +local function drawOpoLeader(v, opoShift, rightSide) if rightSide then opoShift = - opoShift end drawLeaderPath(v, v:getLabelAnchorTikz() .. " -- +(" .. opoShift .. "sp,0) " .. "|- " .. v:getInTextAnchorTikz()) end -function drawOpoGroup(group, directionDown, rightSide) +local function drawOpoGroup(group, directionDown, rightSide) if directionDown == nil then for _, v2 in ipairs(group) do drawOpoLeader(notesForPage[v2], 0, rightSide) @@ -781,7 +847,7 @@ function drawOpoGroup(group, directionDown, rightSide) end end end -function drawOpoLeadersSide(notes, rightSide) +local function drawOpoLeadersSide(notes, rightSide) table.sort(notes, compareNoteIndInputYDesc) local lastDirectionDown = nil @@ -820,7 +886,7 @@ function drawOpoLeadersSide(notes, rightSide) end drawOpoGroup(group, lastDirectionDown, rightSide) end -function drawOpoLeaders() +local function drawOpoLeaders() local notesLeft, notesRight = segmentNotes(notesForPage) if #notesLeft > 0 then drawOpoLeadersSide(notesLeft, false) @@ -835,7 +901,7 @@ leaderTypes["opo"] = {algo = drawOpoLeaders, -- ** leader drawing: po-leaders -function drawPoLeaders() +local function drawPoLeaders() for _, v in ipairs(notesForPage) do drawLeaderPath(v, v:getLabelAnchorTikz() .. " -| " .. v:getInTextAnchorTikz()) end @@ -845,7 +911,7 @@ leaderTypes["po"] = {algo = drawPoLeaders} -- ** leader drawing: os-leaders -function drawOsLeaders() +local function drawOsLeaders() for _, v in ipairs(notesForPage) do local cornerX if v.rightSide then @@ -873,12 +939,12 @@ leaderTypes["os"] = {algo = drawOsLeaders, -- forceLimitInc -- settings for algorithm -maxIterations = 1000 -factorRepulsiveControlPoint = 1 -factorAttractingControlPoint = 1 -stopCondition = 65536 -- corresponds to 1pt +local maxIterations = 1000 +local factorRepulsiveControlPoint = 1 +local factorAttractingControlPoint = 1 +local stopCondition = 65536 -- corresponds to 1pt -function constructCurve(l) +local function constructCurve(l) local curve = {} -- site @@ -903,60 +969,7 @@ function constructCurve(l) return curve end -function computeRepulsiveControlPointForces() - for k1, l1 in pairs(notesForPage) do - for k2, l2 in pairs(notesForPage) do - if k1 ~= k2 then - -- curves of the leaders - local curve1 = constructCurve(l1) - local curve2 = constructCurve(l2) - - local distance = checkCurveApproximation(curve1, curve2); - - -- check if R1 has to be increased or decreased to increase the distance of the 2 curves - -- if curve1 is bent into the direction of curve2, R1 has to be decreased - local actualR = math.abs(labelArea:getXTextSide(l1.rightSide) - l1.movableControlPointX) - if ((l1.inputY < l1.leaderArmY and - l2.leaderArmY < l1.leaderArmY) or - (l1.inputY > l1.leaderArmY and - l2.leaderArmY > l1.leaderArmY)) then - -- R1 has to be increased - local desiredR = math.abs(labelArea:getXTextSide(l1.rightSide) - l1.optimalPositionX) - local diff = math.abs(desiredR - actualR) - if distance == 0 then - distance = 0.01 - end - local force = diff / distance - local newForce = force * factorRepulsiveControlPoint - l1.currentForce = l1.currentForce + newForce - l1.forceLimitDec = math.min(l1.forceLimitDec, distance * 0.45) - else - -- R1 has to be decreased - if distance == 0 then - distance = 0.01 - end - local force = actualR / distance - local newForce = -force * factorRepulsiveControlPoint - l1.currentForce = l1.currentForce + newForce - local oldLim = l1.forceLimitInc - l1.forceLimitInc = math.min(l1.forceLimitInc, distance * 0.45) - --if oldLim ~= l1.forceLimitInc then - --print(k1 .. ": Reduced forceLimitInc from " .. oldLim .. " to " .. l1.forceLimitInc .. " because of " .. k2 .. " (distance: " .. distance .. ")") - --end - end - end - end - end -end -function computeAttractingControlPointForces() - for _, l in pairs(notesForPage) do - local desiredR = math.abs(labelArea:getXTextSide(l.rightSide) - l.optimalPositionX) - local actualR = math.abs(labelArea:getXTextSide(l.rightSide) - l.movableControlPointX) - local newForce = (desiredR - actualR) * factorAttractingControlPoint - l.currentForce = l.currentForce + newForce - end -end -function getPointOnCurve(t, curve) +local function getPointOnCurve(t, curve) if #curve ~= 4 then error("4 points needed for a Bezier-curve. Given size was: " .. #curve) end @@ -973,7 +986,21 @@ function getPointOnCurve(t, curve) return x, y end -function checkCurveApproximation(curve1, curve2) +local function getDistance(line1, line2) + local t1, t2 = pathLine.line_line_intersection(line1.x1, line1.y1, line1.x2, line1.y2, + line2.x1, line2.y1, line2.x2, line2.y2) + if 0 <= t1 and t1 <= 1 and 0 <= t2 and t2 <= 1 then + -- the lines do intersect + return 0 + end + + local d1 = pathLine.hit(line2.x1, line2.y1, line1.x1, line1.y1, line1.x2, line1.y2) + local d2 = pathLine.hit(line2.x2, line2.y2, line1.x1, line1.y1, line1.x2, line1.y2) + local d3 = pathLine.hit(line1.x1, line1.y1, line2.x1, line2.y1, line2.x2, line2.y2) + local d4 = pathLine.hit(line1.x2, line1.y2, line2.x1, line2.y1, line2.x2, line2.y2) + return math.sqrt(math.min(d1, d2, d3, d4)) +end +local function checkCurveApproximation(curve1, curve2) -- these lists will contain the sections of the approximation of the two curves local sectionsCurve1 = {} local sectionsCurve2 = {} @@ -1025,21 +1052,60 @@ function checkCurveApproximation(curve1, curve2) return minDistance end -function getDistance(line1, line2) - local t1, t2 = pathLine.line_line_intersection(line1.x1, line1.y1, line1.x2, line1.y2, - line2.x1, line2.y1, line2.x2, line2.y2) - if 0 <= t1 and t1 <= 1 and 0 <= t2 and t2 <= 1 then - -- the lines do intersect - return 0 - end +local function computeRepulsiveControlPointForces() + for k1, l1 in pairs(notesForPage) do + for k2, l2 in pairs(notesForPage) do + if k1 ~= k2 then + -- curves of the leaders + local curve1 = constructCurve(l1) + local curve2 = constructCurve(l2) - local d1 = pathLine.hit(line2.x1, line2.y1, line1.x1, line1.y1, line1.x2, line1.y2) - local d2 = pathLine.hit(line2.x2, line2.y2, line1.x1, line1.y1, line1.x2, line1.y2) - local d3 = pathLine.hit(line1.x1, line1.y1, line2.x1, line2.y1, line2.x2, line2.y2) - local d4 = pathLine.hit(line1.x2, line1.y2, line2.x1, line2.y1, line2.x2, line2.y2) - return math.sqrt(math.min(d1, d2, d3, d4)) + local distance = checkCurveApproximation(curve1, curve2); + + -- check if R1 has to be increased or decreased to increase the distance of the 2 curves + -- if curve1 is bent into the direction of curve2, R1 has to be decreased + local actualR = math.abs(labelArea:getXTextSide(l1.rightSide) - l1.movableControlPointX) + if ((l1.inputY < l1.leaderArmY and + l2.leaderArmY < l1.leaderArmY) or + (l1.inputY > l1.leaderArmY and + l2.leaderArmY > l1.leaderArmY)) then + -- R1 has to be increased + local desiredR = math.abs(labelArea:getXTextSide(l1.rightSide) - l1.optimalPositionX) + local diff = math.abs(desiredR - actualR) + if distance == 0 then + distance = 0.01 + end + local force = diff / distance + local newForce = force * factorRepulsiveControlPoint + l1.currentForce = l1.currentForce + newForce + l1.forceLimitDec = math.min(l1.forceLimitDec, distance * 0.45) + else + -- R1 has to be decreased + if distance == 0 then + distance = 0.01 + end + local force = actualR / distance + local newForce = -force * factorRepulsiveControlPoint + l1.currentForce = l1.currentForce + newForce + local oldLim = l1.forceLimitInc + l1.forceLimitInc = math.min(l1.forceLimitInc, distance * 0.45) + --if oldLim ~= l1.forceLimitInc then + --print(k1 .. ": Reduced forceLimitInc from " .. oldLim .. " to " .. l1.forceLimitInc .. " because of " .. k2 .. " (distance: " .. distance .. ")") + --end + end + end + end + end end -function applyForces(v) +local function computeAttractingControlPointForces() + for _, l in pairs(notesForPage) do + local desiredR = math.abs(labelArea:getXTextSide(l.rightSide) - l.optimalPositionX) + local actualR = math.abs(labelArea:getXTextSide(l.rightSide) - l.movableControlPointX) + local newForce = (desiredR - actualR) * factorAttractingControlPoint + l.currentForce = l.currentForce + newForce + end +end +local function applyForces(v) --print("force on note " .. v.index .. ": " .. v.currentForce .. " (limit: +" .. v.forceLimitInc .. ", -" .. v.forceLimitDec .. ")") -- limit the force so the movable control point is between the port and the optimal position @@ -1073,7 +1139,7 @@ function applyForces(v) v.currentForce = 0 return c end -function getAngle(centerX, centerY, x, y) +local function getAngle(centerX, centerY, x, y) local vectorX = x - centerX local vectorY = y - centerY local length = math.sqrt((vectorX ^ 2) + (vectorY ^ 2)) @@ -1090,7 +1156,7 @@ function getAngle(centerX, centerY, x, y) return degAngle end -function solveQuadraticEquation(a, b, c) +local function solveQuadraticEquation(a, b, c) local discr = (b * b) - (4 * a * c) if discr < 0 then @@ -1110,7 +1176,7 @@ function solveQuadraticEquation(a, b, c) return solution1 end end -function computeOptimalPosition(v) +local function computeOptimalPosition(v) local distance = point.distance(v.inputX, v.inputY, labelArea:getXTextSide(v.rightSide), v.leaderArmY) -- the angle at the port between the point and the movable control point @@ -1144,7 +1210,7 @@ function computeOptimalPosition(v) v.optimalPositionX = labelArea:getXTextSide(v.rightSide) + r end end -function drawSBezierLeaders() +local function drawSBezierLeaders() for _, v in pairs(notesForPage) do -- initialise leader v.leaderArmY = v:getLabelAnchorY() @@ -1194,9 +1260,9 @@ function drawSBezierLeaders() local curve = constructCurve(v) local unmovableStr = "(" .. curve[2].x .. "sp," .. curve[2].y .. "sp)" local movableStr = "(" .. curve[3].x .. "sp," .. curve[3].y .. "sp)" - drawLeaderPath(v, v:getInTextAnchorTikz() .. " .. controls " .. - unmovableStr .. " and " .. movableStr .. " .. " .. - v:getLabelAnchorTikz()) + drawLeaderPath(v, v:getLabelAnchorTikz() .. " .. controls " .. + movableStr .. " and " .. unmovableStr .. " .. " .. + v:getInTextAnchorTikz()) -- draw control points when requested if todonotesDebug then @@ -1220,26 +1286,11 @@ leaderTypes["sBezier"] = {algo = drawSBezierLeaders} -- ** helper functions --- divides notes in two lists (for left and right side) --- side must be stored in note.rightSide for every note before using this function -function segmentNotes(notes) - local availableNotesLeft = {} - local availableNotesRight = {} - for k, v in pairs(notes) do - if v.rightSide == true then - table.insert(availableNotesRight, k) - else - table.insert(availableNotesLeft, k) - end - end - return availableNotesLeft, availableNotesRight -end - -- finds the index in the list given as parameter with the minimum angle -- the function used for computation of the angle is given as second parameter -- (the alphaFormula gets the note, to which the angle should be computed, as -- the only parameter) -function findIndexMinAlpha(availableNotesIndex, alphaFormula) +local function findIndexMinAlpha(availableNotesIndex, alphaFormula) local minAlpha = math.huge -- infinity local minIndex = -1 @@ -1257,7 +1308,7 @@ end -- ** partition into stacks -function getMeanYHeight(stack) +local function getMeanYHeight(stack) -- TODO: Alternative: nicht das arithmetische Mittel verwenden, sondern -- Mittelpunkt zwischen dem obersten und untersten Punkt local sumY = 0 @@ -1278,7 +1329,7 @@ function getMeanYHeight(stack) end return meanY, height end -function stacksIntersect(stackTop, stackBottom) +local function stacksIntersect(stackTop, stackBottom) local topMeanY, topHeight = getMeanYHeight(stackTop) local topLower = topMeanY - topHeight/2 @@ -1291,7 +1342,7 @@ function stacksIntersect(stackTop, stackBottom) return false end end -function findStacks(notesOnSide) +local function findStacks(notesOnSide) local notes = table.copy(notesOnSide) table.sort(notes, compareNoteIndInputYDesc) @@ -1327,7 +1378,7 @@ end -- ** positioning: inText -function posInText() +local function posInText() -- trivial algorithm -- places notes in text on position where todo-command was issued for k, v in ipairs(notesForPage) do @@ -1342,22 +1393,8 @@ positioningAlgos["inText"] = {algo = posInText, --- ** positioning: inputOrder --- start at top and place notes below each other on left/right side --- notes are placed in the order induced by their y-coordinates -function posInputOrder(notes, rightSide) - table.sort(notes, compareNoteIndInputYDesc) - placeNotesInputOrder(notes, labelArea:getArea(rightSide).top, rightSide) -end -positioningAlgos["inputOrder"] = {algo = posInputOrder, - leaderAnchor = "east", - leaderShift = false, - twoSided = true} - - - -- ** positioning: inputOrderStacks -function placeNotesInputOrder(stack, yStart, rightSide) +local function placeNotesInputOrder(stack, yStart, rightSide) local freeY = yStart for _, k in ipairs(stack) do @@ -1367,7 +1404,7 @@ function placeNotesInputOrder(stack, yStart, rightSide) freeY = freeY - v:getHeight() - 2 * noteInnerSep - noteInterSpace end end -function posInputOrderStacks(notesOnSide, rightSide) +local function posInputOrderStacks(notesOnSide, rightSide) table.sort(notesOnSide, compareNoteIndInputYDesc) local stacks = findStacks(notesOnSide) @@ -1386,8 +1423,22 @@ positioningAlgos["inputOrderStacks"] = {algo = posInputOrderStacks, +-- ** positioning: inputOrder +-- start at top and place notes below each other on left/right side +-- notes are placed in the order induced by their y-coordinates +local function posInputOrder(notes, rightSide) + table.sort(notes, compareNoteIndInputYDesc) + placeNotesInputOrder(notes, labelArea:getArea(rightSide).top, rightSide) +end +positioningAlgos["inputOrder"] = {algo = posInputOrder, + leaderAnchor = "east", + leaderShift = false, + twoSided = true} + + + -- ** positioning: sLeaderNorthEast -function posSLeaderNorthEast(notes, rightSide) +local function posSLeaderNorthEast(notes, rightSide) local noteY = labelArea:getArea(rightSide).top local alphaFormula @@ -1423,7 +1474,7 @@ positioningAlgos["sLeaderNorthEast"] = {algo = posSLeaderNorthEast, -- ** positioning: sLeaderNorthEastBelow -function placeNotesNorthEastBelow(stack, yStart, rightSide) +local function placeNotesNorthEastBelow(stack, yStart, rightSide) -- calculate minimum height of all notes local minHeight = math.huge -- (infinity) for _, v in pairs(stack) do @@ -1462,7 +1513,7 @@ function placeNotesNorthEastBelow(stack, yStart, rightSide) table.remove(availableNotes, minIndex) end end -function posSLeaderNorthEastBelow(notes, rightSide) +local function posSLeaderNorthEastBelow(notes, rightSide) placeNotesNorthEastBelow(notes, labelArea:getArea(rightSide).top, rightSide) end positioningAlgos["sLeaderNorthEastBelow"] = {algo = posSLeaderNorthEastBelow, @@ -1473,7 +1524,7 @@ positioningAlgos["sLeaderNorthEastBelow"] = {algo = posSLeaderNorthEastBelow, -- ** positioning: sLeaderNorthEastBelowStacks -function posSLeaderNorthEastBelowStacks(notesOnSide, rightSide) +local function posSLeaderNorthEastBelowStacks(notesOnSide, rightSide) local stacks = findStacks(notesOnSide) -- place stacks @@ -1491,7 +1542,7 @@ positioningAlgos["sLeaderNorthEastBelowStacks"] = {algo = posSLeaderNorthEastBel -- ** positioning: sLeaderEast -function posSLeaderEast(notes, rightSide) +local function posSLeaderEast(notes, rightSide) local leaderPosY local noteY = labelArea:getArea(rightSide).top @@ -1634,13 +1685,13 @@ positioningAlgos["sLeaderEast"] = {algo = posSLeaderEast, -- ** positioning: poLeaders -function getRasterAbsolute(rasterHeight, top, rasterIndex) +local function getRasterAbsolute(rasterHeight, top, rasterIndex) return top - (rasterIndex - 1) * rasterHeight end -- distance between line and leader that algorithm tries to reach when there is -- no neighbouring line local poMinDistLine = string.todimen("4pt") -function getPosAboveLine(linePositionsCurPage, lineInd) +local function getPosAboveLine(linePositionsCurPage, lineInd) local line = linePositionsCurPage[lineInd] local posAbove if linePositionsCurPage[lineInd - 1] ~= nil then @@ -1651,7 +1702,7 @@ function getPosAboveLine(linePositionsCurPage, lineInd) end return posAbove end -function getPosBelowLine(linePositionsCurPage, lineInd) +local function getPosBelowLine(linePositionsCurPage, lineInd) local line = linePositionsCurPage[lineInd] local posBelow if linePositionsCurPage[lineInd + 1] ~= nil then @@ -1662,7 +1713,7 @@ function getPosBelowLine(linePositionsCurPage, lineInd) end return posBelow end -function posPoLeaders(notes, rightSide, avoidLines) +local function posPoLeaders(notes, rightSide, avoidLines) print("rasterHeight: " .. rasterHeight) local linePositionsCurPage @@ -1998,8 +2049,8 @@ function posPoLeaders(notes, rightSide, avoidLines) -- DEBUG on page if todonotesDebug then tex.print("\\node[text=blue,fill=white,rectangle,align=center] at (10.5cm,-27cm) {" .. - "total length: " .. number.tocentimeters(length) .. "\\\\ " .. - "rasterHeight: " .. number.tocentimeters(rasterHeight) .. + "total length: " .. number.tocentimeters(length, "%s%s") .. "\\\\ " .. + "rasterHeight: " .. number.tocentimeters(rasterHeight, "%s%s") .. "};") end @@ -2025,7 +2076,7 @@ positioningAlgos["poLeaders"] = {algo = posPoLeaders, leaderShift = false, twoSided = true} -function posPoLeadersAvoid(notes, rightSide) +local function posPoLeadersAvoid(notes, rightSide) posPoLeaders(notes, rightSide, true) end positioningAlgos["poLeadersAvoidLines"] = {algo = posPoLeadersAvoid, @@ -2041,7 +2092,7 @@ positioningAlgos["poLeadersAvoidLines"] = {algo = posPoLeadersAvoid, -- ** splittingAlgorithm: none -- place all notes on the wider side -function splitNone() +local function splitNone() local rightSideSelected = false if labelArea.left == nil and labelArea.right == nil then error("Cannot place labels on any side of text (not enough space). " .. @@ -2064,7 +2115,7 @@ splittingAlgos["none"] = {algo = splitNone} -- ** splittingAlgorithm: middle -- split on middle of page -function splitMiddle() +local function splitMiddle() if labelArea:isOneSided() then splitNone() else @@ -2084,7 +2135,7 @@ splittingAlgos["middle"] = {algo = splitMiddle} -- ** splittingAlgorithm: median -- split at median (sites sorted by x-coordinate) -function splitMedian() +local function splitMedian() if labelArea:isOneSided() then splitNone() else @@ -2122,7 +2173,7 @@ splittingAlgos["median"] = {algo = splitMedian} -- ** splittingAlgorithm: weightedMedian -- split at weighted median (sites sorted by x-coordinate) -- sum of heights of labels on both sides are similiar to each other -function splitWeightedMedian() +local function splitWeightedMedian() if labelArea:isOneSided() then splitNone() else diff --git a/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.sty b/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.sty index 6f7a193ccce..d300a1ba5ad 100644 --- a/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.sty +++ b/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.sty @@ -8,7 +8,7 @@ %% %% This is a generated file. %% -%% Copyright (C) 2014 by Fabian Lipp <fabian.lipp@gmx.de> +%% Copyright (C) 2014-2015 by Fabian Lipp <fabian.lipp@gmx.de> %% based on the todonotes package by %% Henrik Skov Midtiby <henrikmidtiby@gmail.com> %% @@ -24,9 +24,15 @@ %% \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{luatodonotes} - [2014/08/07 v0.1 luatodonotes source and documentation.] + [2015/03/13 v0.2 luatodonotes source and documentation.] -\ProvidesPackage{luatodonotes}[2014/06/08] +\RequirePackage{ifluatex} +\ifluatex\else + \PackageError{luatodonotes}{LuaTeX is required for this package. Aborting.}{% + This package can only be used with the LuaTeX engine\MessageBreak + (command `lualatex'). Package loading has been stopped\MessageBreak + to prevent additional errors.} +\fi \RequirePackage{ifthen} \RequirePackage{xkeyval} \RequirePackage{xcolor} @@ -56,7 +62,7 @@ \newcommand{\@todonotes@interNoteSpace}{5pt} \newcommand{\@todonotes@noteInnerSep}{5pt} \newcommand{\@todonotes@routingAreaWidth}{0.4cm} -\newcommand{\@todonotes@minNoteWidth}{2.0cm} +\newcommand{\@todonotes@minNoteWidth}{1.0cm} \newcommand{\@todonotes@distanceNotesPageBorder}{0.5cm} \newcommand{\@todonotes@distanceNotesText}{0.2cm} \newcommand{\@todonotes@rasterHeight}{1cm} @@ -242,62 +248,29 @@ \newdimen\@todonotes@fontsize \newdimen\@todonotes@currentsidemargin \directlua{require("luatodonotes")} -\directlua{noteInnerSep = +\directlua{luatodonotes.noteInnerSep = string.todimen("\luatexluaescapestring{\@todonotes@noteInnerSep}")} -\directlua{noteInterSpace = +\directlua{luatodonotes.noteInterSpace = string.todimen("\luatexluaescapestring{\@todonotes@interNoteSpace}")} -\directlua{routingAreaWidth = +\directlua{luatodonotes.routingAreaWidth = string.todimen("\luatexluaescapestring{\@todonotes@routingAreaWidth}")} -\directlua{minNoteWidth = +\directlua{luatodonotes.minNoteWidth = string.todimen("\luatexluaescapestring{\@todonotes@minNoteWidth}")} -\directlua{distanceNotesPageBorder = +\directlua{luatodonotes.distanceNotesPageBorder = string.todimen("\luatexluaescapestring{\@todonotes@distanceNotesPageBorder}")} -\directlua{distanceNotesText = +\directlua{luatodonotes.distanceNotesText = string.todimen("\luatexluaescapestring{\@todonotes@distanceNotesText}")} -\directlua{rasterHeight = +\directlua{luatodonotes.rasterHeight = string.todimen("\luatexluaescapestring{\@todonotes@rasterHeight}")} -\IfStrEqCase{\@todonotes@positioning}{% - {inText}{\directlua{positioning = positioningAlgos["inText"]}}% - {inputOrder}{\directlua{positioning = positioningAlgos["inputOrder"]}}% - {inputOrderStacks}{\directlua{positioning = - positioningAlgos["inputOrderStacks"]}}% - {sLeaderNorthEast}{\directlua{positioning = - positioningAlgos["sLeaderNorthEast"]}}% - {sLeaderNorthEastBelow}{\directlua{positioning = - positioningAlgos["sLeaderNorthEastBelow"]}}% - {sLeaderEast}{\directlua{positioning = - positioningAlgos["sLeaderEast"]}}% - {poLeaders}{\directlua{positioning = positioningAlgos["poLeaders"]}}% - {poLeadersAvoidLines}{\directlua{positioning = - positioningAlgos["poLeadersAvoidLines"]}}% - {sLeaderNorthEastBelowStacks}{\directlua{positioning = - positioningAlgos["sLeaderNorthEastBelowStacks"]}}}% - [\directlua{positioning = positioningAlgos["inputOrderStacks"]} - \PackageWarningNoLine{luatodonotes} - {Invalid value for parameter positioning: \@todonotes@positioning}] -\IfStrEqCase{\@todonotes@splitting}{% - {none}{\directlua{splitting = splittingAlgos["none"]}}% - {middle}{\directlua{splitting = splittingAlgos["middle"]}}% - {median}{\directlua{splitting = splittingAlgos["median"]}}% - {weightedMedian}{\directlua{splitting = splittingAlgos["weightedMedian"]}}}% - [\directlua{splitting = splittingAlgos["none"]} - \PackageWarningNoLine{luatodonotes} - {Invalid value for parameter split: \@todonotes@splitting}] -\IfStrEqCase{\@todonotes@leadertype}{% - {s}{\directlua{leaderType = leaderTypes["s"]}}% - {opo}{\directlua{leaderType = leaderTypes["opo"]}}% - {po}{\directlua{leaderType = leaderTypes["po"]}}% - {sBezier}{\directlua{leaderType = leaderTypes["sBezier"]}}% - {os}{\directlua{leaderType = leaderTypes["os"]}}}% - [\directlua{leaderType = leaderTypes["opo"]} - \PackageWarningNoLine{luatodonotes} - {Invalid value for parameter leadertype: \@todonotes@leadertype}] +\directlua{luatodonotes.setPositioningAlgo("\luatexluaescapestring{\@todonotes@positioning}")} +\directlua{luatodonotes.setSplittingAlgo("\luatexluaescapestring{\@todonotes@splitting}")} +\directlua{luatodonotes.setLeaderType("\luatexluaescapestring{\@todonotes@leadertype}")} \def\@todonotes@pdflastypos{\the\pdflastypos} \newcommand{\@todonotes@lineposition}[3]{% - \directlua{linePositionsAddLine(#1,#2,#3)}% + \directlua{luatodonotes.linePositionsAddLine(#1,#2,#3)}% } \newcommand{\@todonotes@nextpage}{% - \directlua{linePositionsNextPage()}% + \directlua{luatodonotes.linePositionsNextPage()}% }% \newcommand{\@todonotes@writeNextpageToLpo}{% \ifdefined\tf@lpo% @@ -305,15 +278,15 @@ \fi } \if@todonotes@debugenabled - \directlua{todonotesDebug = true} + \directlua{luatodonotes.todonotesDebug = true} \newcommand{\@todonotes@AtBeginShipoutUpperLeft} {\AtBeginShipoutUpperLeftForeground} \else - \directlua{todonotesDebug = false} + \directlua{luatodonotes.todonotesDebug = false} \newcommand{\@todonotes@AtBeginShipoutUpperLeft} {\AtBeginShipoutUpperLeft} \fi -\directlua{initTodonotes()} +\directlua{luatodonotes.initTodonotes()} \soulregister{\ }{0} \newlength{\todonotes@textmark@width} \newlength{\todonotes@textmark@fontsize} @@ -336,7 +309,7 @@ {% last line of area \def\todonotes@textmark@decoRight{}% \addtolength\todonotes@textmark@width{2pt}% - \directlua{processLastLineInTodoArea()}}% + \directlua{luatodonotes.processLastLineInTodoArea()}}% {\def\todonotes@textmark@decoRight{@todonotes@todoarea}% \addtolength\todonotes@textmark@width{4pt}}% \newcommand{\@todonotes@nodeNamePrefix}% @@ -543,7 +516,13 @@ \edef\@todonotes@tmp{\@todonotes@currentleaderwidth}% \@todonotes@toks@currentleaderwidth=\expandafter{\@todonotes@tmp}% \@todonotes@toks@sizecommand=\expandafter{\@todonotes@sizecommand}% - \savebox\@todonotes@notetextbox{\@todonotes@sizecommand\@todonotes@text}% + \savebox\@todonotes@notetextbox{% + \@parboxrestore + \@marginparreset + \@todonotes@sizecommand\@todonotes@text% + \@minipagefalse + \outer@nobreak + }% \if@todonotes@line% \def\@todonotes@param@drawLeader{true}% \else% @@ -554,7 +533,7 @@ \else% \def\@todonotes@param@noteType{}% \fi% - \directlua{addNoteToList(\arabic{@todonotes@numberoftodonotes},% + \directlua{luatodonotes.addNoteToList(\arabic{@todonotes@numberoftodonotes},% \@todonotes@param@drawLeader,\luastringO{\@todonotes@param@noteType})}% }% \newcommand{\@todonotes@addElementToListOfTodos}{% @@ -612,19 +591,17 @@ \checkoddpage% \ifoddpageoroneside% \@todonotes@currentsidemargin=\the\oddsidemargin% - \directlua{currentPageOdd = true}% \else% \@todonotes@currentsidemargin=\the\evensidemargin% - \directlua{currentPageOdd = false}% \fi\relax% \BeginCatcodeRegime\CatcodeTableLaTeX - \directlua{calcLabelAreaDimensions()}% - \directlua{calcHeightsForNotes()}% has to be outside of tikzpicture + \directlua{luatodonotes.calcLabelAreaDimensions()}% + \directlua{luatodonotes.calcHeightsForNotes()}% has to be outside of tikzpicture \begin{tikzpicture}[remember picture,overlay] - \directlua{getInputCoordinatesForNotes()} - \directlua{printNotes()} + \directlua{luatodonotes.getInputCoordinatesForNotes()} + \directlua{luatodonotes.printNotes()} \end{tikzpicture}% - \directlua{clearNotes()}% + \directlua{luatodonotes.clearNotes()}% \EndCatcodeRegime }% } |