Giter Club home page Giter Club logo

Comments (2)

philipp-kempgen avatar philipp-kempgen commented on June 18, 2024

Yes, truncating a string to a certain length including the omission string is the most common use case, I'd say.

Sometimes I could even use something like .truncate_inspect that returns "truncated_string"..., i.e. the omission string (if applicable) goes after the .truncated and .inspected string.
Probably be a niche case, where you really need to make clear what was part of the original string and what wasn't.

from crystal.

philipp-kempgen avatar philipp-kempgen commented on June 18, 2024

I'm proposing something like this.

Maybe there should be an option to not break Unicode grapheme clusters, regional indicators, flag sequences, tag sequences and whatnot.

class String
  
  # Truncates the string to a given length *`truncate_to`*.
  #
  # The last characters will be replaced with the *`omission`* string
  # (defaults to '`…`') if necessary. The total length will not exceed
  # *`truncate_to`*.
  #
  # Optionally pass a `Char`, `String` or `Regex` separator *`sep`*, such as
  # `/\b/` (word boundary), to truncate text at a natural break.
  # Optionally set *`sep_max_lose`* to the maximum number of characters you
  # want to lose by cutting at a natural break. Otherwise a cut will still be
  # made at an arbitrary position. (Defaults to `nil`.)
  # Also see `.truncate_at_word_boundary` for truncating a string at word
  # boundaries.
  #
  # Raises `ArgumentError` if *`truncate_to`* < 1.
  #
  # Raises `ArgumentError` if *`truncate_to`* < the length of the omission
  # string.
  #
  # Raises `ArgumentError` if *`sep_max_lose`* is < 0 (and separator *`sep`*
  # is specified).
  #
  def truncate(
    truncate_to  : Int32,
    *,
    omission     : (Char | String)? = '…',
    sep          : (Char | String | Regex)? = nil,
    sep_max_lose : Int32? = nil,
  ) : String
    return self  if size <= truncate_to  # no need to truncate
    
    if truncate_to < 1
      raise ArgumentError.new "Invalid truncate value: #{truncate_to}"
    end
    
    omission_len = case omission
      when Char  ; 1
      when String; omission.size
      when Nil   ; 0
      else raise "Invalid omission of type #{typeof(omission)}."
    end
    
    if truncate_to < omission_len
      raise ArgumentError.new "Can't truncate to #{truncate_to} when the omission has #{omission_len} characters (#{omission.inspect})."
    end
    
    cut_len = truncate_to - omission_len  # length with room for omission
    if sep
      sep_pos = rindex( sep, cut_len )
      if sep_max_lose && sep_max_lose.negative?
        raise ArgumentError.new "sep_max_lose must not be negative."
      end
      if sep_pos && ((! sep_max_lose) || (sep_pos >= cut_len - sep_max_lose))
        cut_len = sep_pos
      end
    end
    
    return String.build( cut_len + omission_len ){ |s|
      s << self[ 0, cut_len ]
      s << omission  if omission
    }
  end
  
  # Truncates the string to a given length *`truncate_to`*, trying to respect word boundaries.
  #
  # See *`.truncate`* for details and exceptions.
  #
  def truncate_at_word_boundary( truncate_to : Int32, *, omission : String = "", sep_max_lose : Int32? = 10 )
    return truncate( truncate_to, omission: omission, sep: /\b/, sep_max_lose: sep_max_lose )
  end
end

from crystal.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.