From 5ec21fd1c60e0aa6fcd566e687fd5199695f855d Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 7 Mar 2023 22:22:01 +0000 Subject: linebreaker (7mar23) git-svn-id: svn://tug.org/texlive/trunk@66440 c570f23f-e606-0410-a88d-b1316a301751 --- .../tex/lualatex/linebreaker/linebreaker.lua | 72 +++++++++++++++++++--- .../tex/lualatex/linebreaker/linebreaker.sty | 9 +++ 2 files changed, 74 insertions(+), 7 deletions(-) (limited to 'Master/texmf-dist/tex') diff --git a/Master/texmf-dist/tex/lualatex/linebreaker/linebreaker.lua b/Master/texmf-dist/tex/lualatex/linebreaker/linebreaker.lua index 6a2d20e074b..99966ad302f 100644 --- a/Master/texmf-dist/tex/lualatex/linebreaker/linebreaker.lua +++ b/Master/texmf-dist/tex/lualatex/linebreaker/linebreaker.lua @@ -1,3 +1,11 @@ +-- linebreaker.lua +-- +-- (c) Michal Hoftich +-- +-- This program can be redistributed and/or modified under the terms +-- of the LaTeX Project Public License Distributed from CTAN archives +-- in directory macros/latex/base/lppl.txt. + local linebreaker = {} local hlist_id = node.id "hlist" @@ -22,7 +30,7 @@ end linebreaker.debug = false -- max allowed value of tolerance -linebreaker.max_tolerance = 9999 +linebreaker.max_tolerance = 8189 -- maximal possible value of tolerance (thanks to Jan Šustek for pointing that out) -- maximal allowed emergencystretch linebreaker.max_emergencystretch = tex.sp("3em") -- line breaking function is customizable @@ -43,9 +51,38 @@ linebreaker.previous_points = linebreaker.vertical_point / linebreaker.boxsize linebreaker.width_factor = 1.5 -- will be linebreaker active? linebreaker.active = true + +-- use cubic method for tolerance calculation +linebreaker.use_cubic = false -- return array with default parameters function linebreaker.parameters() - return {} + return { + pardir = tex.pardir + ,pretolerance = tex.pretolerance + ,tracingparagraphs=tex.tracingparagraphs + ,tolerance=tex.tolerance + ,looseness=tex.looseness + ,hyphenpenalty=tex.hyphenpenalty + ,exhyphenpenalty=tex.exhyphenpenalty + ,pdfadjustspacing=tex.pdfadjustspacing + ,adjdemerits=tex.adjdemerits + ,pdfprotrudechars=tex.pdfprotrudechars + ,linepenalty=tex.linepenalty + ,lastlinefit=tex.lastlinefit + ,doublehyphendemerits=tex.doublehyphendemerits + ,finalhyphendemerits=tex.finalhyphendemerits + ,hangafter=tex.hangafter + ,interlinepenalty=tex.interlinepenalty + ,clubpenalty=tex.clubpenalty + ,widowpenalty=tex.widowpenalty + ,brokenpenalty=tex.brokenpenalty + ,emergencystretch=tex.emergencystretch + ,hangindent=tex.hangindent + ,hsize=tex.hsize + ,leftskip=tex.leftskip + ,rightskip=tex.rightskip + ,parshape=tex.parshape + } end -- diagnostic function for traversing nodes returned by linebreaking @@ -144,9 +181,23 @@ local function glue_calc(n, sign,set) end --- calculate new tolerance +local function cube_root(num) + return num ^(1/3) +end + + +-- calculate new tolerance using method suggested by Jan Šustek +local function calc_tolerance_cubic(previous, step) + local previous = previous or tex.tolerance + local max_cycles = linebreaker.max_cycles + local max_tolerance = linebreaker.max_tolerance + local new = 100 * (cube_root(previous / 100) + (cube_root(max_tolerance/100) - cube_root(previous/100)) * (step/max_cycles))^3 + -- local new = previous + (max_tolerance / max_cycles)-- + math.sqrt(previous * 4) + return (new < max_tolerance) and new or max_tolerance +end + -- max_tolerance / max_cycles is added to the current tolerance value -local function calc_tolerance(previous) +local function calc_tolerance(previous, step) local previous = previous or tex.tolerance local max_cycles = linebreaker.max_cycles local max_tolerance = linebreaker.max_tolerance @@ -340,7 +391,9 @@ end -- try to linebreak current paragraph with increasing tolerance and -- emergencystretch -function linebreaker.best_solution(par, parameters) +function linebreaker.best_solution(par, parameters, step) + -- step is used in the tolerance calculation + local step = (step or 0) + 1 -- save current node list, because call to the linebreaker modifies it -- and we wouldn't be able to run it multiple times local head = node.copy_list(par) @@ -373,9 +426,14 @@ function linebreaker.best_solution(par, parameters) params.badness = badness if badness > 0 then -- calc new value of tolerance - local tolerance = calc_tolerance(params.tolerance) -- or 10000 + local tolerance + if linebreaker.use_cubic then + tolerance = calc_tolerance_cubic(params.tolerance, step) -- or 10000 + else + tolerance = calc_tolerance(params.tolerance, step) -- or 10000 + end -- save tolerance to newparams so this value will be used in next run - newparams.tolerance = tolerance + newparams.tolerance = math.floor(tolerance) newparams.emergencystretch = (params.emergencystretch or 0) + linebreaker.max_emergencystretch / linebreaker.max_cycles table.insert(parameters, newparams) -- run linebreaker again diff --git a/Master/texmf-dist/tex/lualatex/linebreaker/linebreaker.sty b/Master/texmf-dist/tex/lualatex/linebreaker/linebreaker.sty index 2804f4bbe69..3442adad8c2 100644 --- a/Master/texmf-dist/tex/lualatex/linebreaker/linebreaker.sty +++ b/Master/texmf-dist/tex/lualatex/linebreaker/linebreaker.sty @@ -1,3 +1,11 @@ +% linebreaker.sty +% +% (c) Michal Hoftich +% +%% This program can be redistributed and/or modified under the terms +%% of the LaTeX Project Public License Distributed from CTAN archives +%% in directory macros/latex/base/lppl.txt. + \ProvidesPackage{linebreaker} \RequirePackage{luatexbase} @@ -16,6 +24,7 @@ luatexbase.add_to_callback("hpack_quality", linebreaker.hpack_quality, "Our over maxtolerance .code:n = \directlua{linebreaker.max_tolerance = tonumber("#1")}, maxemergencystretch .code:n = \directlua{linebreaker.max_emergencystretch = tex.sp("#1")}, maxcycles .code:n = \directlua{linebreaker.max_cycles = tonumber("#1")}, + cubic .code:n = \directlua{linebreaker.use_cubic = true} } \NewDocumentCommand{\linebreakersetup}{m}{ \keys_set:nn {linebreaker} {#1} -- cgit v1.2.3