Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement titlecase function. Fix #19465. #19469

Merged
merged 1 commit into from
Dec 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]).
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should doc/NEWS-update.jl be run in order to create the link?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. Done.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we are holding off on running that... we will update a bunch of links at once in a separate PR. Updating the NEWS links in individual PRs creates too many merge conflicts.


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)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll also need to add a placeholder to doc/stdlib/strings.rst for titlecase to be included in the manual, and re-run julia doc/genstdlib.jl

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