diff --git a/spec/std/char_spec.cr b/spec/std/char_spec.cr index f0c81f8d1723..e06a64bdf406 100644 --- a/spec/std/char_spec.cr +++ b/spec/std/char_spec.cr @@ -390,6 +390,15 @@ describe "Char" do '酒'.ascii?.should be_false end + it "#printable?" do + ' '.printable?.should be_true + 'a'.printable?.should be_true + '酒'.printable?.should be_true + '\n'.printable?.should be_false + '\e'.printable?.should be_false + '\uF8FF'.printable?.should be_false + end + describe "clone" do it { 'a'.clone.should eq('a') } end diff --git a/src/char.cr b/src/char.cr index 24b1effd2c8d..6fd2431343fb 100644 --- a/src/char.cr +++ b/src/char.cr @@ -489,11 +489,23 @@ struct Char ascii? ? ascii_control? : Unicode.control?(self) end - # Returns `true` if this is char is a mark character according to unicode. + # Returns `true` if this char is a mark character according to unicode. def mark? : Bool Unicode.mark?(self) end + # Returns `true` if this char is a printable character. + # + # There is no universal definition of printable characters in Unicode. + # For the purpose of this method, all characters with a visible glyph and the + # ASCII whitespace (` `) are considered printable. + # + # This means characters which are `control?` or `whitespace?` (except for ` `) + # are non-printable. + def printable? + !control? && (!whitespace? || self == ' ') + end + # Returns this char as a string that contains a char literal. # # ```