Skip to content

Commit

Permalink
Add support for ANSI color and style-fix issue#15
Browse files Browse the repository at this point in the history
Add support for ANSI color and style-fix issue#15

This change addresses the need by:

Adding new method *colorize*.

Side effects:

New third party dependency, FACE is now a requirement (all other codes
using StringiFor must be updated).
  • Loading branch information
szaghi committed Jan 27, 2020
1 parent e1b3655 commit 568c7be
Show file tree
Hide file tree
Showing 88 changed files with 612 additions and 562 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@
path = src/third_party/BeFoR64
url = https://github.com/szaghi/BeFoR64
branch = master
[submodule "src/third_party/FACE"]
path = src/third_party/FACE
url = git@github.com:szaghi/FACE.git
22 changes: 22 additions & 0 deletions src/lib/stringifor_string_t.F90
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module stringifor_string_t
!< StringiFor, definition of `string` type.
use, intrinsic :: iso_fortran_env, only : iostat_eor
use befor64, only : b64_decode, b64_encode
use face, only : colorize
use penf, only : I1P, I2P, I4P, I8P, R4P, R8P, R16P, str

implicit none
Expand Down Expand Up @@ -44,6 +45,8 @@ module stringifor_string_t
procedure, pass(self) :: camelcase !< Return a string with all words capitalized without spaces.
procedure, pass(self) :: capitalize !< Return a string with its first character capitalized and the rest lowercased.
procedure, pass(self) :: chars !< Return the raw characters data.
generic :: colorize => &
colorize_str !< Colorize and stylize strings.
procedure, pass(self) :: decode !< Decode string.
procedure, pass(self) :: encode !< Encode string.
procedure, pass(self) :: escape !< Escape backslashes (or custom escape character).
Expand Down Expand Up @@ -149,6 +152,7 @@ module stringifor_string_t
procedure, private, pass(self) :: sverify_string_string !< Verify replacement.
procedure, private, pass(self) :: sverify_string_character !< Verify replacement.
! auxiliary methods
procedure, private, pass(self) :: colorize_str !< Colorize and stylize strings.
procedure, private, pass(self) :: glob_character !< Glob search (character output).
procedure, private, pass(self) :: glob_string !< Glob search (string output).
procedure, private, pass(self) :: insert_string !< Insert substring into string at a specified position.
Expand Down Expand Up @@ -930,6 +934,24 @@ pure function chars(self) result(raw)
endif
endfunction chars

pure function colorize_str(self, color_fg, color_bg, style) result(colorized)
!< Colorize and stylize strings, DEFAULT kind.
!<
!<```fortran
!< type(string) :: astring
!< astring = 'say all Hello WorLD!'
!< print '(L1)', astring%colorize(color_fg='red')=='say all Hello WorLD!'
!<```
!=> T <<<
class(string), intent(in) :: self !< The string.
character(len=*), intent(in), optional :: color_fg !< Foreground color definition.
character(len=*), intent(in), optional :: color_bg !< Background color definition.
character(len=*), intent(in), optional :: style !< Style definition.
character(len=:), allocatable :: colorized !< Colorized string.

colorized = colorize(string=self%chars(), color_fg=color_fg, color_bg=color_bg, style=style)
endfunction colorize_str

elemental function decode(self, codec) result(decoded)
!< Return a string decoded accordingly the codec.
!<
Expand Down
13 changes: 13 additions & 0 deletions src/tests/stringifor_string_t/stringifor_string_t-doctest-100.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
character(len=:), allocatable :: acharacter
logical :: test_passed(2)
astring = 'one'
acharacter = 'ONE'
test_passed(1) = ((acharacter<astring).eqv..true.)
astring = 'ONE'
acharacter = 'one'
test_passed(2) = ((acharacter<astring).eqv..false.)
print '(L1)', all(test_passed)
endprogram volatile_doctest
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
T
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
character(len=:), allocatable :: acharacter
type(string) :: anotherstring
logical :: test_passed(3)
astring = 'one'
acharacter = 'ONE'
test_passed(1) = ((astring<=acharacter).eqv..false.)
anotherstring = 'ONE'
test_passed(1) = ((astring<=anotherstring).eqv..false.)
astring = 'ONE'
acharacter = 'one'
test_passed(2) = ((astring<=acharacter).eqv..true.)
anotherstring = 'one'
test_passed(2) = ((astring<=anotherstring).eqv..true.)
astring = 'ONE'
acharacter = 'ONE'
test_passed(3) = ((astring<=acharacter).eqv..true.)
anotherstring = 'ONE'
test_passed(3) = ((astring<=anotherstring).eqv..true.)
print '(L1)', all(test_passed)
endprogram volatile_doctest
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ program volatile_doctest
logical :: test_passed(3)
astring = 'one'
acharacter = 'ONE'
test_passed(1) = ((acharacter<=astring).eqv..true.)
test_passed(1) = ((astring<=acharacter).eqv..false.)
astring = 'ONE'
acharacter = 'one'
test_passed(2) = ((acharacter<=astring).eqv..false.)
test_passed(2) = ((astring<=acharacter).eqv..true.)
astring = 'ONE'
acharacter = 'ONE'
test_passed(3) = ((acharacter<=astring).eqv..true.)
test_passed(3) = ((astring<=acharacter).eqv..true.)
print '(L1)', all(test_passed)
endprogram volatile_doctest
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
type(string) :: anotherstring
character(len=:), allocatable :: acharacter
logical :: test_passed(3)
astring = 'one'
anotherstring = 'ONE'
test_passed(1) = ((astring>=anotherstring).eqv..true.)
acharacter = 'ONE'
test_passed(1) = ((acharacter<=astring).eqv..true.)
astring = 'ONE'
anotherstring = 'one'
test_passed(2) = ((astring>=anotherstring).eqv..false.)
acharacter = 'one'
test_passed(2) = ((acharacter<=astring).eqv..false.)
astring = 'ONE'
anotherstring = 'ONE'
test_passed(3) = ((astring>=anotherstring).eqv..true.)
acharacter = 'ONE'
test_passed(3) = ((acharacter<=astring).eqv..true.)
print '(L1)', all(test_passed)
endprogram volatile_doctest
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
character(len=:), allocatable :: acharacter
type(string) :: anotherstring
logical :: test_passed(3)
astring = 'one'
acharacter = 'ONE'
test_passed(1) = ((astring>=acharacter).eqv..true.)
anotherstring = 'ONE'
test_passed(1) = ((astring>=anotherstring).eqv..true.)
astring = 'ONE'
acharacter = 'one'
test_passed(2) = ((astring>=acharacter).eqv..false.)
anotherstring = 'one'
test_passed(2) = ((astring>=anotherstring).eqv..false.)
astring = 'ONE'
acharacter = 'ONE'
test_passed(3) = ((astring>=acharacter).eqv..true.)
anotherstring = 'ONE'
test_passed(3) = ((astring>=anotherstring).eqv..true.)
print '(L1)', all(test_passed)
endprogram volatile_doctest
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ program volatile_doctest
logical :: test_passed(3)
astring = 'one'
acharacter = 'ONE'
test_passed(1) = ((acharacter>=astring).eqv..false.)
test_passed(1) = ((astring>=acharacter).eqv..true.)
astring = 'ONE'
acharacter = 'one'
test_passed(2) = ((acharacter>=astring).eqv..true.)
test_passed(2) = ((astring>=acharacter).eqv..false.)
astring = 'ONE'
acharacter = 'ONE'
test_passed(3) = ((acharacter>=astring).eqv..true.)
test_passed(3) = ((astring>=acharacter).eqv..true.)
print '(L1)', all(test_passed)
endprogram volatile_doctest
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
type(string) :: anotherstring
logical :: test_passed(2)
character(len=:), allocatable :: acharacter
logical :: test_passed(3)
astring = 'one'
anotherstring = 'ONE'
test_passed(1) = ((astring>anotherstring).eqv..true.)
acharacter = 'ONE'
test_passed(1) = ((acharacter>=astring).eqv..false.)
astring = 'ONE'
anotherstring = 'one'
test_passed(2) = ((astring>anotherstring).eqv..false.)
acharacter = 'one'
test_passed(2) = ((acharacter>=astring).eqv..true.)
astring = 'ONE'
acharacter = 'ONE'
test_passed(3) = ((acharacter>=astring).eqv..true.)
print '(L1)', all(test_passed)
endprogram volatile_doctest
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
character(len=:), allocatable :: acharacter
type(string) :: anotherstring
logical :: test_passed(2)
astring = 'one'
acharacter = 'ONE'
test_passed(1) = ((astring>acharacter).eqv..true.)
anotherstring = 'ONE'
test_passed(1) = ((astring>anotherstring).eqv..true.)
astring = 'ONE'
acharacter = 'one'
test_passed(2) = ((astring>acharacter).eqv..false.)
anotherstring = 'one'
test_passed(2) = ((astring>anotherstring).eqv..false.)
print '(L1)', all(test_passed)
endprogram volatile_doctest
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ program volatile_doctest
logical :: test_passed(2)
astring = 'one'
acharacter = 'ONE'
test_passed(1) = ((acharacter>astring).eqv..false.)
test_passed(1) = ((astring>acharacter).eqv..true.)
astring = 'ONE'
acharacter = 'one'
test_passed(2) = ((acharacter>astring).eqv..true.)
test_passed(2) = ((astring>acharacter).eqv..false.)
print '(L1)', all(test_passed)
endprogram volatile_doctest
13 changes: 13 additions & 0 deletions src/tests/stringifor_string_t/stringifor_string_t-doctest-109.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
character(len=:), allocatable :: acharacter
logical :: test_passed(2)
astring = 'one'
acharacter = 'ONE'
test_passed(1) = ((acharacter>astring).eqv..false.)
astring = 'ONE'
acharacter = 'one'
test_passed(2) = ((acharacter>astring).eqv..true.)
print '(L1)', all(test_passed)
endprogram volatile_doctest
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
T
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
astring = 'SG93IGFyZSB5b3U/'
print '(L1)', astring%decode(codec='base64')//''=='How are you?'
astring = 'say all Hello WorLD!'
print '(L1)', astring%colorize(color_fg='red')=='[31msay all Hello WorLD![0m'
endprogram volatile_doctest
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
astring = 'How are you?'
print '(L1)', astring%encode(codec='base64')//''=='SG93IGFyZSB5b3U/'
astring = 'SG93IGFyZSB5b3U/'
print '(L1)', astring%decode(codec='base64')//''=='How are you?'
endprogram volatile_doctest
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
logical :: test_passed(2)
astring = '^\s \d+\s*'
test_passed(1) = astring%escape(to_escape='\')//''=='^\\s \\d+\\s*'
test_passed(2) = astring%escape(to_escape='\', esc='|')//''=='^|\s |\d+|\s*'
print '(L1)', all(test_passed)
astring = 'How are you?'
print '(L1)', astring%encode(codec='base64')//''=='SG93IGFyZSB5b3U/'
endprogram volatile_doctest
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
astring = '/bar/foo.tar.bz2'
print '(L1)', astring%extension()//''=='.bz2'
logical :: test_passed(2)
astring = '^\s \d+\s*'
test_passed(1) = astring%escape(to_escape='\')//''=='^\\s \\d+\\s*'
test_passed(2) = astring%escape(to_escape='\', esc='|')//''=='^|\s |\d+|\s*'
print '(L1)', all(test_passed)
endprogram volatile_doctest
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
logical :: test_passed(4)
astring = 'this is string example....wow!!!'
test_passed(1) = astring%fill(width=40)//''=='00000000this is string example....wow!!!'
test_passed(2) = astring%fill(width=50)//''=='000000000000000000this is string example....wow!!!'
test_passed(3) = astring%fill(width=50, right=.true.)//''=='this is string example....wow!!!000000000000000000'
test_passed(4) = astring%fill(width=40, filling_char='*')//''=='********this is string example....wow!!!'
print '(L1)', all(test_passed)
astring = '/bar/foo.tar.bz2'
print '(L1)', astring%extension()//''=='.bz2'
endprogram volatile_doctest
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
logical :: test_passed(4)
astring = 'this is string example....wow!!!'
call astring%free
print '(L1)', astring%is_allocated().eqv..false.
test_passed(1) = astring%fill(width=40)//''=='00000000this is string example....wow!!!'
test_passed(2) = astring%fill(width=50)//''=='000000000000000000this is string example....wow!!!'
test_passed(3) = astring%fill(width=50, right=.true.)//''=='this is string example....wow!!!000000000000000000'
test_passed(4) = astring%fill(width=40, filling_char='*')//''=='********this is string example....wow!!!'
print '(L1)', all(test_passed)
endprogram volatile_doctest
29 changes: 3 additions & 26 deletions src/tests/stringifor_string_t/stringifor_string_t-doctest-34.f90
Original file line number Diff line number Diff line change
@@ -1,30 +1,7 @@
program volatile_doctest
use stringifor_string_t
type(string) :: astring
character(len=:), allocatable :: alist_chr(:)
integer, parameter :: Nf=5
character(14) :: files(1:Nf)
integer :: file_unit
integer :: f
integer :: ff
logical :: test_passed
do f=1, Nf
files(f) = astring%tempname(prefix='foo-')
open(newunit=file_unit, file=files(f))
write(file_unit, *)f
close(unit=file_unit)
enddo
call astring%glob(pattern='foo-*', list=alist_chr)
do f=1, Nf
open(newunit=file_unit, file=files(f))
close(unit=file_unit, status='delete')
enddo
test_passed = .false.
outer_chr: do f=1, size(alist_chr, dim=1)
do ff=1, Nf
test_passed = alist_chr(f) == files(ff)
if (test_passed) cycle outer_chr
enddo
enddo outer_chr
print '(L1)', test_passed
astring = 'this is string example....wow!!!'
call astring%free
print '(L1)', astring%is_allocated().eqv..false.
endprogram volatile_doctest
Loading

0 comments on commit 568c7be

Please sign in to comment.