paragraph(3f) - [M_strings:TOKENS] break a long line into a paragraph
(LICENSE:PD)
function paragraph(source_string,length)
character(len=*),intent(in) :: source_string
integer,intent(in) :: length
character(allocatable(len=length) :: paragraph(:)
paragraph(3f) breaks a long line into a simple paragraph of specified
line length.
Given a long string break it on spaces into an array such that no
variable is longer than the specified length. Individual words longer
than LENGTH will be placed in variables by themselves.
SOURCE_STRING input string to break into an array of shorter strings
on blank delimiters
LENGTH length of lines to break the string into.
PARAGRAPH character array filled with data from source_string
broken at spaces into variables of length LENGTH.
sample program
program demo_paragraph
use M_strings, only : paragraph
implicit none
character(len=:),allocatable :: paragrph(:)
character(len=*),parameter :: string= '&
&one two three four five &
&six seven eight &
&nine ten eleven twelve &
&thirteen fourteen fifteen sixteen &
&seventeen'
write(*,*)'LEN=',len(string)
write(*,*)'INPUT:'
write(*,*)string
paragrph=paragraph(string,40)
write(*,*)'LEN=',len(paragrph),' SIZE=',size(paragrph)
write(*,*)'OUTPUT:'
write(*,'(a)')paragrph
write(*,'(a)')paragraph(string,0)
write(*,'(3x,a)')paragraph(string,47)
end program demo_paragraph
Results:
LEN= 106
INPUT:
one two three four five six seven eight nine ten eleven twelve
thirteen fourteen fifteen sixteen seventeen
LEN= 40 SIZE= 3
OUTPUT:
one two three four five six seven eight
nine ten eleven twelve thirteen fourteen
fifteen sixteen seventeen
one
two
three
four
five
six
seven
eight
nine
ten
eleven
twelve
thirteen
fourteen
fifteen
sixteen
seventeen
one two three four five six seven eight nine
ten eleven twelve thirteen fourteen fifteen
sixteen seventeen
John S. Urban
Public Domain
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
character(len=*), | intent(in) | :: | source_string | |||
integer, | intent(in) | :: | length |
function paragraph(source_string,length)
! ident_84="@(#) M_strings paragraph(3f) wrap a long string into a paragraph"
character(len=*),intent(in) :: source_string
integer,intent(in) :: length
integer :: itoken
integer :: istart
integer :: iend
character(len=*),parameter :: delimiters=' '
character(len=:),allocatable :: paragraph(:)
integer :: ilines
integer :: ilength
integer :: iword, iword_max
integer :: i
!-----------------------------------------------------------------------------------------------------------------------------------
! parse string once to find out how big to make the returned array, then redo everything but store the data
! could store array of endpoints and leave original whitespace alone or many other options
do i=1,2
iword_max=0 ! length of longest token
ilines=1 ! number of output line output will go on
ilength=0 ! length of output line so far
itoken=0 ! must set ITOKEN=0 before looping on strtok(3f) on a new string.
do while ( strtok(source_string,itoken,istart,iend,delimiters) )
iword=iend-istart+1
iword_max=max(iword_max,iword)
if(iword > length)then ! this token is longer than the desired line length so put it on a line by itself
if(ilength /= 0)then
ilines=ilines+1
endif
if(i == 2)then ! if paragraph has been allocated store data, else just gathering data to determine size of paragraph
paragraph(ilines)=source_string(istart:iend)//' '
endif
ilength=iword+1
elseif(ilength+iword <= length)then ! this word will fit on current line
if(i == 2)then
paragraph(ilines)=paragraph(ilines)(:ilength)//source_string(istart:iend)
endif
ilength=ilength+iword+1
else ! adding this word would make line too long so start new line
ilines=ilines+1
ilength=0
if(i == 2)then
paragraph(ilines)=paragraph(ilines)(:ilength)//source_string(istart:iend)
endif
ilength=iword+1
endif
enddo
if(i==1)then ! determined number of lines needed so allocate output array
allocate(character(len=max(length,iword_max)) :: paragraph(ilines))
paragraph=' '
endif
enddo
paragraph=paragraph(:ilines)
end function paragraph