Truncating padded text

I’ve often wished that rpad and lpad would truncate to the given width if they’re already wider than n — do we have a function or succinct idiom for that somewhere?

1 Like

Not that I can recall. It could be implemented as a keyword option to rpad and lpad.

One tricky part of this is that truncating text can make it longer (specifically with languages like Arabic where final characters sometimes have different rendering).

2 Likes

Right now our textwidth function is monotonic, based on a relatively simple model for how terminals render characters. (Terminals don’t generally know about the kind of ligatures you are talking about, I think?)

Even for things as common as emoji characters, terminals don’t all agree on the widths, so it’s impossible to do perfect column alignment without having lower-level/terminal-specific knowledge of the text-rendering engine. See the infamous issue: Julia doesn't like Pizza · Issue #3721 · JuliaLang/julia · GitHub

2 Likes

If you use Format.jl, you can do either cfmt("%10.10s", str) or pyfmt("10.10s", str), to both pad and truncate to the given width & precision.
Note that this is broken on Formatting.jl.
Also note that Printf.jl currently has a bug with truncating strings that have characters that have textwidth > 1 (I just discovered yesterday that while implementing the precision argument for strings for the Python style formatting)

1 Like

That’s not really working as I’d hope. Second thing I tried:

julia> using Format

julia> cfmt("%10.10s", "🍕🍕🍕🍕🍕🍕")
"    🍕🍕🍕🍕\xf0\x9f\x8d/LLVM"

With --checkbounds=yes:

julia> cfmt("%10.10s", "🍕🍕🍕🍕🍕🍕")
ERROR: BoundsError: attempt to access 23-element Vector{UInt8} at index [24]

Ah - sorry! I haven’t gotten the fix for cfmt checked in yet. Later today!
It is already fixed for the Python format function (pyfmt).

julia> pyfmt(“10.10s”, “:pizza::pizza::pizza::pizza::pizza::pizza:”)
:pizza::pizza::pizza::pizza::pizza:

Also, here is an example of where @sprintf/@printf give the wrong result:

julia> @sprintf("%10.9s", "🍕🍕🍕🍕🍕🍕")
" 🍕🍕🍕🍕"

julia> textwidth(ans)
9

(it should be padded with 2 spaces, so that the result is 10 wide)

It’s fixed now! I thought I’d gotten that part of the changes commited before I made the PR, but was just too quick for my own good!

1 Like