<commit_before>SILE.scratch.insertions = { classes = {} }

SILE.insertions = {}

local initInsertionClass = function (self, classname, options)
  SU.required(options, "insertInto", "initializing insertions")
  SU.required(options, "stealFrom", "initializing insertions")
  SU.required(options, "maxHeight", "initializing insertions")
  if not options.topSkip and not options.topBox then
    SU.required(options, "topSkip", "initializing insertions")
  end

  -- Turn stealFrom into a hash, if it isn't one.
  if type(options.stealFrom) == "string" then options.stealFrom = { options.stealFrom } end
  if options.stealFrom[1] then
    local rl = {}
    for i = 1,#(options.stealFrom) do rl[options.stealFrom[i]] = 1 end
    options.stealFrom = rl
  end
  SILE.scratch.insertions.classes[classname] = options
end

-- This initializes a vbox to store all the material in an insertion
-- class for the current page
local insertionsThisPage = {}
local _pageInsertionVbox = SILE.nodefactory.newVbox({
  __tostring = function(self) return "PI<"..self.nodes..">" end,
  outputYourself = function (self)
    if not self.typesetter then
      self.typesetter = SILE.defaultTypesetter {}
      self.typesetter:init(SILE.getFrame(self.frame))
    end
    for i = 1,#self.nodes do local n = self.nodes[i]
      n:outputYourself(self.typesetter, n)
    end
  end
})

local thisPageInsertionBoxForClass = function(class)
  if not insertionsThisPage[class] then
    local this = std.tree.clone(_pageInsertionVbox)
    this.frame  = SILE.scratch.insertions.classes[class].insertInto
    insertionsThisPage[class] = this
  end
  return insertionsThisPage[class]
end

local _insertionVbox = SILE.nodefactory.newVbox({
  __tostring = function(self) return "I<"..self.nodes..">" end,
  outputYourself = function(self)
    for i = 1,#(self.nodes) do
      thisPageInsertionBoxForClass(self.class):append(self.nodes[i])
    end
  end,
  type = "insertionVbox"
})

SILE.insertions.setShrinkage = function(classname, amount)
  SU.debug("insertions", "Shrinking main box by "..amount.length)
  local reduceList = SILE.scratch.insertions.classes[classname].stealFrom
  for fName, ratio in pairs(reduceList) do local f = SILE.getFrame(fName)
    if not f.state.totals then f:init() end -- May be a frame that has not been entered yet
    if not f.state.totals.shrinkage then f.state.totals.shrinkage = 0 end
    f.state.totals.shrinkage = f.state.totals.shrinkage + amount.length * ratio
  end

  -- Calculate the total size of insertions so far this page as negative shrinkage...
  f = SILE.getFrame(SILE.scratch.insertions.classes[classname].insertInto)
  if not f.state.totals then f:init() end
  if not f.state.totals.shrinkage then f.state.totals.shrinkage = 0 end
  f.state.totals.shrinkage = f.state.totals.shrinkage - amount.length

end

SILE.insertions.commitShrinkage = function(classname)
  local opts = SILE.scratch.insertions.classes[classname]
  local reduceList = opts["stealFrom"]
  local stealPosition = opts["steal-position"] or "bottom"
  for fName, ratio in pairs(reduceList) do local f = SILE.getFrame(fName)
    if not f.state.totals then f:init() end -- May be a frame that has not been entered yet
    if not f.state.totals.shrinkage then f.state.totals.shrinkage = 0 end
    local newHeight = f:height() - f.state.totals.shrinkage<commit_msg>Refactor common code.<commit_after>SILE.scratch.insertions = { classes = {} }

SILE.insertions = {}

local initInsertionClass = function (self, classname, options)
  SU.required(options, "insertInto", "initializing insertions")
  SU.required(options, "stealFrom", "initializing insertions")
  SU.required(options, "maxHeight", "initializing insertions")
  if not options.topSkip and not options.topBox then
    SU.required(options, "topSkip", "initializing insertions")
  end

  -- Turn stealFrom into a hash, if it isn't one.
  if type(options.stealFrom) == "string" then options.stealFrom = { options.stealFrom } end
  if options.stealFrom[1] then
    local rl = {}
    for i = 1,#(options.stealFrom) do rl[options.stealFrom[i]] = 1 end
    options.stealFrom = rl
  end
  SILE.scratch.insertions.classes[classname] = options
end

-- This initializes a vbox to store all the material in an insertion
-- class for the current page
local insertionsThisPage = {}
local _pageInsertionVbox = SILE.nodefactory.newVbox({
  __tostring = function(self) return "PI<"..self.nodes..">" end,
  outputYourself = function (self)
    if not self.typesetter then
      self.typesetter = SILE.defaultTypesetter {}
      self.typesetter:init(SILE.getFrame(self.frame))
    end
    for i = 1,#self.nodes do local n = self.nodes[i]
      n:outputYourself(self.typesetter, n)
    end
  end
})

local thisPageInsertionBoxForClass = function(class)
  if not insertionsThisPage[class] then
    local this = std.tree.clone(_pageInsertionVbox)
    this.frame  = SILE.scratch.insertions.classes[class].insertInto
    insertionsThisPage[class] = this
  end
  return insertionsThisPage[class]
end

local _insertionVbox = SILE.nodefactory.newVbox({
  __tostring = function(self) return "I<"..self.nodes..">" end,
  outputYourself = function(self)
    for i = 1,#(self.nodes) do
      thisPageInsertionBoxForClass(self.class):append(self.nodes[i])
    end
  end,
  type = "insertionVbox"
})

-- Set up a value to track how much smaller/larger to make a frame.
-- We have to track this on the frame, because different insertion
-- classes might affect the same frame; so we can't track it per class.
-- We also have to ensure it's initialized every time because we might
-- be shrinking a frame further down the page that the typesetter hasn't
-- entered yet.
local initShrinkage = function (f)
  if not f.state.totals then f:init() end
  if not f.state.totals.shrinkage then f.state.totals.shrinkage = 0 end
end

SILE.insertions.setShrinkage = function(classname, amount)
  SU.debug("insertions", "Shrinking main box by "..amount.length)
  local reduceList = SILE.scratch.insertions.classes[classname].stealFrom
  for fName, ratio in pairs(reduceList) do local f = SILE.getFrame(fName)
    initShrinkage(f)
    f.state.totals.shrinkage = f.state.totals.shrinkage + amount.length * ratio
  end

  -- Calculate the total size of insertions so far this page as negative shrinkage...
  f = SILE.getFrame(SILE.scratch.insertions.classes[classname].insertInto)
  initShrinkage(f)
  f.state.totals.shrinkage = f.state.totals.shrinkage - amount.length

end

SILE.insertions.commitShrinkage = function(classname)
  local opts = SILE.scratch.insertions.classes[classname]
  local reduceList = opts["stealFrom"]
  local stealPosition = opts["steal-position"] or "bottom"
  for fName, ratio in pairs(reduceList) do local f = SILE.getFrame(fName)
    initShrinkage(f)
    local newHeight = f:height() - f.state.totals.shrinkage
{'fraction_non_alphanumeric': 0.10920551158018177, 'fraction_numerical': 0.0020521841102316037, 'mean_word_length': 4.110861423220974, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3271995', 'n_tokens_mistral': 2306, 'n_tokens_neox': 2223, 'n_words': 592}