# assign penalty to one discretionary (not all paragraph)

For a quite complex problem that would be too long to describe, I need to set different penalties for different discretionaries in the same paragraphe. It doesn't seem to be possible with pdfTeX (and LuaTeX has a bug with it, but it's a different problem).

First I tried (these are all Plain TeX MWE):

abc\penalty-10001\discretionary{d}{e}{f}ghi\bye


but this doesn't break on the discretionary itself. Then I tried

abc\hyphenpenalty -10001\discretionary{d}{e}{f}ghi\bye


which works under pdfTeX, but when I try

abc\hyphenpenalty -10001\discretionary{d}{e}{f}ghi\hyphenpenalty 10001\discretionary{d}{e}{f}\bye


it doesn't work anymore (discretionaries penalty seem to all get the last one defined in the paragraph). Is there a way, in "normal" TeX or LuaTeX to do what I'm trying to achieve?

 As it doesn't seem possible, I've proposed patches for the LuaTeX binary on this thread.

[Re-edit] Feature request is reported here. After discussion with the team, it won't be done before TL2015, but will certainly appear aferwards.

• The value of \hyphenpenalty current at the time \par is sensed is used for the whole paragraph, so changing it in the middle does not work. Mar 14, 2015 at 14:03
• hence my question... Mar 14, 2015 at 14:03
• If the paragraphs are sufficiently long to give the line breaking algorithm room to manoeuvre then you can force an "invisible" paragraph break with {\parfillskip=0pt\par\parskip=0pt\noindent}. See problem 14.15 in the TeXBook. Could that help? Mar 14, 2015 at 14:16
• Interesting idea... but the layout is quite convoluted, and these discretionaries will appear around 10 times in one line... so it doesn't seem possible... ? Mar 14, 2015 at 14:19

Using the test release of luatex 0.85 I get from

\tracingoutput1
\tracingonline1
\showboxdepth1000

abc\begingroup\hyphenpenalty -10001\discretionary{d}{e}{f}\endgroup
ghi\begingroup\hyphenpenalty 10001\discretionary{d}{e}{f}\endgroup

\bye


and a log

Completed box being shipped out [1]
\vbox(667.20255+0.0)x469.75499, direction TLT
.\vbox(0.0+0.0)x469.75499, glue set 14.0fil, direction TLT
..\glue -22.5
..\hbox(8.5+0.0)x469.75499, glue set 469.755fil, direction TLT
...\vbox(8.5+0.0)x0.0, direction TLT
...\glue 0.0 plus 1.0fil
..\glue 0.0 plus 1.0fil minus 1.0fil
.\vbox(643.20255+0.0)x469.75499, glue set 619.25812fill, direction TLT
..\glue(\topskip) 3.05556
..\hbox(6.94444+0.0)x469.75499, direction TLT
...\localpar
....\localinterlinepenalty=0
....\localbrokenpenalty=0
....\localleftbox=null
....\localrightbox=null
...\hbox(0.0+0.0)x20.0, direction TLT
...\tenrm a
...\tenrm b
...\kern0.27779
...\tenrm c
...\tenrm d
...\discretionary-10001|
...\glue(\rightskip) 0.0
..\penalty 400
..\glue(\baselineskip) 5.05556
..\hbox(6.94444+1.94444)x469.75499, glue set 448.9216fil, direction TLT
...\tenrm e
...\tenrm g
...\tenrm h
...\tenrm i
...\discretionary10001| replacing
....\tenrm f
....\tenrm d
...|\tenrm e
...\penalty 10000
...\glue(\parfillskip) 0.0 plus 1.0fil
...\glue(\rightskip) 0.0
..\glue 0.0 plus 1.0fill
.\glue(\baselineskip) 17.55556
.\hbox(6.44444+0.0)x469.75499, glue set 232.37749fil, direction TLT
..\glue 0.0 plus 1.0fil minus 1.0fil
..\tenrm 1
..\glue 0.0 plus 1.0fil minus 1.0fil


Showing that each of the discretionary nodes has recorded its local value of \hyphenpenalty

• Do you think you could submit the idea to XeTeX developers too? I tried to submit a few ideas from LuaTeX to the xetex mailing list but never got answers... Dec 3, 2015 at 10:17
• I certainly could, although it might be harder there xetex is still mostly written in web and closer in many ways to the original tex source, so it's not so easy to extend the underlying model I'd guess (although I could be wrong:-) Dec 3, 2015 at 10:20
• That may be worth a try! My previous attempt was here Dec 3, 2015 at 10:27

So, as egreg wrote earlier you cannot assign different penalties to different discretionaries within a paragraph.

So, after TeX has read the paragraph, it starts its line breaking task. Potential breakpoints are rated upon their associated penalty. The penalties associated with discretionary breakpoints are the values for \hyphenpenalty respectively \exhyphenpenalty which are in force at the end of the paragraph.
By stating \penaltyp you are inserting a potential breakpoint with an assoctiated penalty p. If p ≤ -10000 TeX will always break at this breakpoint.
Thus, if you input abc\penalty-10001\discretionary{d}{e}{f}ghi to TeX, you force a break at the \penalty and while TeX is choosing the remaining breakpoints, the potential breakpoint you inserted by \discretionary{d}{e}{f} is (still) taken into account with a penalty of the value of \hyphenpenalty that was current at the end of the paragraph.