From 73687e8727760388383dfe67aeda0f6461533a47 Mon Sep 17 00:00:00 2001 From: ScottPJones Date: Thu, 15 Feb 2024 08:35:27 -0500 Subject: [PATCH] Fix issue #83 (from Formatting.jl), handle precision argument for Python format string --- Project.toml | 2 +- src/fmtcore.jl | 47 +++++++++++++++++++++++++++++++++-------------- test/fmtspec.jl | 10 ++++++++++ 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/Project.toml b/Project.toml index 5903583..c177ca6 100644 --- a/Project.toml +++ b/Project.toml @@ -23,7 +23,7 @@ keywords = ["Strings", "Formatting"] license = "MIT" name = "Format" uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" -version = "1.3.3" +version = "1.3.4" [deps] diff --git a/src/fmtcore.jl b/src/fmtcore.jl index c54a641..e02fd7b 100644 --- a/src/fmtcore.jl +++ b/src/fmtcore.jl @@ -13,24 +13,43 @@ function _repprint(out::IO, c::AbstractChar, n::Int) end end - ### print string or char +function _truncstr(s::AbstractString, slen, prec) + prec == 0 && return ("", 0) + i, n = 0, 1 + siz = ncodeunits(s) + while n <= siz + (prec -= textwidth(s[n])) < 0 && break + i = n + n = nextind(s, i) + end + str = SubString(s, 1, i) + return (str, textwidth(str)) +end + +_truncstr(s::AbstractChar, slen, prec) = ("", 0) + function _pfmt_s(out::IO, fs::FormatSpec, s::Union{AbstractString,AbstractChar}) - pad = fs.width - textwidth(s) - if pad <= 0 - print(out, s) - elseif fs.align == '<' - print(out, s) - _repprint(out, fs.fill, pad) - elseif fs.align == '^' - _repprint(out, fs.fill, pad>>1) - print(out, s) - _repprint(out, fs.fill, (pad+1)>>1) - else - _repprint(out, fs.fill, pad) - print(out, s) + slen = textwidth(s) + str, slen = 0 <= fs.prec < slen ? _truncstr(s, slen, fs.prec) : (s, slen) + prepad = postpad = 0 + pad = fs.width - slen + if pad > 0 + if fs.align == '<' + postpad = pad + elseif fs.align == '^' + prepad, postpad = pad>>1, (pad+1)>>1 + else + prepad = pad + end end + # left padding + prepad == 0 || _repprint(out, fs.fill, prepad) + # print string + print(out, str) + # right padding + postpad == 0 || _repprint(out, fs.fill, postpad) end _unsigned_abs(x::Signed) = unsigned(abs(x)) diff --git a/test/fmtspec.jl b/test/fmtspec.jl index 90b52a7..b4e98f2 100644 --- a/test/fmtspec.jl +++ b/test/fmtspec.jl @@ -54,6 +54,7 @@ end @test pyfmt("#b", 6) == "0b110" @test pyfmt("#o", 6) == "0o6" @test pyfmt("#x", 6) == "0x6" + @test pyfmt("#X", 10) == "0XA" end @testset "Format string" begin @@ -75,6 +76,15 @@ end @test pyfmt("⋆^5s", "αβγ") == "⋆αβγ⋆" @test pyfmt("*<5s", "abc") == "abc**" @test pyfmt("⋆<5s", "αβγ") == "αβγ⋆⋆" + + # Issue #83 (in Formatting.jl) + @test pyfmt(".3s", "\U1f595\U1f596") == "🖕" + @test pyfmt(".4s", "\U1f595\U1f596") == "🖕🖖" + @test pyfmt(".5s", "\U1f595\U1f596") == "🖕🖖" + + @test pyfmt("6.3s", "\U1f595\U1f596") == "🖕 " + @test pyfmt("6.4s", "\U1f595\U1f596") == "🖕🖖 " + @test pyfmt("6.5s", "\U1f595\U1f596") == "🖕🖖 " end @testset "Format Symbol" begin