Skip to content

Commit

Permalink
Implement titlecase function. Fix JuliaLang#19465. (JuliaLang#19469)
Browse files Browse the repository at this point in the history
Clarify docstring.

Single-pass version without call to lowercase.

Test subsequent spaces.

NEWS.md entry and RST docs.

Add NEWS.md links.
  • Loading branch information
helgee authored and stevengj committed Dec 6, 2016
1 parent dedd3cd commit 6f8e94e
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 2 deletions.
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ Library improvements

* New `accumulate` and `accumulate!` functions, which generalize `cumsum` and `cumprod`. Also known as a [scan](https://en.wikipedia.org/wiki/Prefix_sum) operation ([#18931]).

* New `titlecase` function, which capitalizes the first character of each word within a string ([#19469]).

Compiler/Runtime improvements
-----------------------------

Expand Down Expand Up @@ -706,8 +708,10 @@ Language tooling improvements
[#18442]: https://github.com/JuliaLang/julia/issues/18442
[#18473]: https://github.com/JuliaLang/julia/issues/18473
[#18839]: https://github.com/JuliaLang/julia/issues/18839
[#18931]: https://github.com/JuliaLang/julia/issues/18931
[#18977]: https://github.com/JuliaLang/julia/issues/18977
[#19018]: https://github.com/JuliaLang/julia/issues/19018
[#19233]: https://github.com/JuliaLang/julia/issues/19233
[#19288]: https://github.com/JuliaLang/julia/issues/19288
[#19305]: https://github.com/JuliaLang/julia/issues/19305
[#19469]: https://github.com/JuliaLang/julia/issues/19469
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,7 @@ export
strip,
strwidth,
summary,
titlecase,
transcode,
ucfirst,
unescape_string,
Expand Down
27 changes: 26 additions & 1 deletion base/strings/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ byte_string_classify(s::String) = byte_string_classify(s.data)
isvalid(::Type{String}, s::Union{Vector{UInt8},String}) = byte_string_classify(s) != 0
isvalid(s::String) = isvalid(String, s)

## uppercase and lowercase transformations ##
## uppercase, lowercase, and titlecase transformations ##

"""
uppercase(s::AbstractString)
Expand All @@ -402,6 +402,31 @@ julia> lowercase("STRINGS AND THINGS")
"""
lowercase(s::AbstractString) = map(lowercase, s)

"""
titlecase(s::AbstractString)
Capitalizes the first character of each word in `s`.
```jldoctest
julia> titlecase("the julia programming language")
"The Julia Programming Language"
```
"""
function titlecase(s::AbstractString)
startword = true
b = IOBuffer()
for c in s
if isspace(c)
print(b, c)
startword = true
else
print(b, startword ? titlecase(c) : c)
startword = false
end
end
return String(take!(b))
end

"""
ucfirst(s::AbstractString)
Expand Down
3 changes: 2 additions & 1 deletion base/strings/utf8proc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Various Unicode functionality from the utf8proc library
module UTF8proc

import Base: show, ==, hash, string, Symbol, isless, length, eltype, start, next, done, convert, isvalid, lowercase, uppercase
import Base: show, ==, hash, string, Symbol, isless, length, eltype, start, next, done, convert, isvalid, lowercase, uppercase, titlecase

export isgraphemebreak

Expand Down Expand Up @@ -159,6 +159,7 @@ charwidth(c::Char) = Int(ccall(:utf8proc_charwidth, Cint, (UInt32,), c))

lowercase(c::Char) = isascii(c) ? ('A' <= c <= 'Z' ? c + 0x20 : c) : Char(ccall(:utf8proc_tolower, UInt32, (UInt32,), c))
uppercase(c::Char) = isascii(c) ? ('a' <= c <= 'z' ? c - 0x20 : c) : Char(ccall(:utf8proc_toupper, UInt32, (UInt32,), c))
titlecase(c::Char) = isascii(c) ? ('a' <= c <= 'z' ? c - 0x20 : c) : Char(ccall(:utf8proc_totitle, UInt32, (UInt32,), c))

############################################################################

Expand Down
11 changes: 11 additions & 0 deletions doc/stdlib/strings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,17 @@
julia> lowercase("STRINGS AND THINGS")
"strings and things"

.. function:: titlecase(s::AbstractString)

.. Docstring generated from Julia source
Capitalizes the first character of each word in ``s``\ .

.. doctest::

julia> titlecase("the julia programming language")
"The Julia Programming Language"

.. function:: ucfirst(s::AbstractString)

.. Docstring generated from Julia source
Expand Down
6 changes: 6 additions & 0 deletions test/strings/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,12 @@ end
@test lcfirst(GenericString("a")) == "a"
@test ucfirst(GenericString("A")) == "A"

# titlecase
@test titlecase('lj') == 'Lj'
@test titlecase("ljubljana") == "Ljubljana"
@test titlecase("aBc ABC") == "ABc ABC"
@test titlecase("abcD EFG\n\thij") == "AbcD EFG\n\tHij"

# issue # 11464: uppercase/lowercase of GenericString becomes a String
str = "abcdef\uff\uffff\u10ffffABCDEF"
@test typeof(uppercase("abcdef")) == String
Expand Down

0 comments on commit 6f8e94e

Please sign in to comment.