truncate_to_width Function

public pure function truncate_to_width(text, width) result(cut)

Cut text to at most width columns, never mid-character and never inside an escape sequence.

Escape sequences are kept and cost nothing, so a styled row keeps its colours and is cut by what it shows rather than by how it is spelled. Note that a cut can leave an attribute set with its reset dropped; ansi_reset() after writing a truncated row settles that.

A width of zero still keeps nothing at all, escape sequences included: a caller asking for no columns wants no bytes.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: text

Text to truncate.

integer(kind=default_int), intent(in) :: width

Maximum width in columns.

Return Value character(len=:), allocatable


Calls

proc~~truncate_to_width~~CallsGraph proc~truncate_to_width truncate_to_width proc~escape_length escape_length proc~truncate_to_width->proc~escape_length

Called by

proc~~truncate_to_width~~CalledByGraph proc~truncate_to_width truncate_to_width proc~frame_set_line frame_t%frame_set_line proc~frame_set_line->proc~truncate_to_width

Variables

Type Visibility Attributes Name Initial
integer(kind=default_int), private :: byte
integer(kind=default_int), private :: i
integer(kind=default_int), private :: last
integer(kind=default_int), private :: seen
integer(kind=default_int), private :: skip

Source Code

   pure function truncate_to_width(text, width) result(cut)
      !! Cut `text` to at most `width` columns, never mid-character and never
      !! inside an escape sequence.
      !!
      !! Escape sequences are kept and cost nothing, so a styled row keeps its
      !! colours and is cut by what it shows rather than by how it is spelled.
      !! Note that a cut can leave an attribute set with its reset dropped;
      !! `ansi_reset()` after writing a truncated row settles that.
      !!
      !! A `width` of zero still keeps nothing at all, escape sequences
      !! included: a caller asking for no columns wants no bytes.
      character(len=*), intent(in) :: text
         !! Text to truncate.
      integer(default_int), intent(in) :: width
         !! Maximum width in columns.
      character(len=:), allocatable :: cut

      integer(default_int) :: i, byte, seen, skip, last

      if (width <= 0_default_int) then
         cut = ""
         return
      end if

      seen = 0_default_int
      last = len(text, kind=default_int)
      i = 1_default_int
      do while (i <= last)
         skip = escape_length(text, i)
         if (skip > 0_default_int) then
            i = i + skip
            cycle
         end if
         byte = iachar(text(i:i), default_int)
         if (byte < 128_default_int .or. byte >= 192_default_int) then
            if (seen == width) then
               cut = text(1:i - 1_default_int)
               return
            end if
            seen = seen + 1_default_int
         end if
         i = i + 1_default_int
      end do
      cut = text
   end function truncate_to_width