Class: Y::Text

Inherits:
Object
  • Object
show all
Defined in:
lib/y/text.rb

Overview

A text can be used insert and remove string fragments. It also supports formatting and the concept of embeds, which are supported data types that added as metadata.

The text is the replicated counterpart to a String. It supports a subset of String operations, like appending, insert at position and slicing.

Someone should not instantiate a text directly, but use Doc#get_text instead.

Examples:

doc = Y::Doc.new
text = doc.get_text("my text")

text << "Hello, World!"
puts text.to_s

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(doc = nil) ⇒ Text

Create a new text instance

Parameters:

  • doc (Y::Doc) (defaults to: nil)


29
30
31
32
33
# File 'lib/y/text.rb', line 29

def initialize(doc = nil)
  @document = doc || Y::Doc.new

  super()
end

Instance Attribute Details

#documentY::Doc

Returns The document this text belongs to.

Returns:

  • (Y::Doc)

    The document this text belongs to



24
25
26
# File 'lib/y/text.rb', line 24

def document
  @document
end

Instance Method Details

#<<(str) ⇒ void

This method returns an undefined value.

Appends a string at the end of the text

Parameters:

  • str (String)


39
40
41
# File 'lib/y/text.rb', line 39

def <<(str)
  document.current_transaction { |tx| ytext_push(tx, str) }
end

#attach(callback, &block) ⇒ Integer

Attach listener to text changes

Examples:

Listen to changes in text type

local = Y::Doc.new

text = local.get_text("my text")
text.attach(->(delta) { pp delta }) # { insert: "Hello, World!" }

local.transact do
  text << "Hello, World!"
end

Listen to changes in text type

local = Y::Doc.new

text = local.get_text("my text")
text.attach(->(delta) { pp delta }) # { insert: "Hello, World!" }

text << "Hello, World!"

# todo: required, otherwise segfault
local.commit

Parameters:

  • callback (Proc)
  • block (Block)

Returns:

  • (Integer)


69
70
71
72
73
# File 'lib/y/text.rb', line 69

def attach(callback, &block)
  return ytext_observe(callback) unless callback.nil?

  ytext_observe(block.to_proc) unless block.nil?
end

#detach(subscription_id) ⇒ void

This method returns an undefined value.

Detach listener

Parameters:

  • subscription_id (Integer)


79
80
81
# File 'lib/y/text.rb', line 79

def detach(subscription_id)
  ytext_unobserve(subscription_id)
end

#empty?TrueClass, FalseClass

Checks if text is empty

Examples:

Check if text is empty

doc = Y::Doc.new
text = doc.get_text("my text")

text.empty? # true

Returns:

  • (TrueClass, FalseClass)


92
93
94
# File 'lib/y/text.rb', line 92

def empty?
  length.zero?
end

#format(index, length, attrs) ⇒ void

This method returns an undefined value.

Applies formatting to text

Examples:

Add formatting to first word

doc = Y::Doc.new
text = doc.get_text("my text")

attrs = {format: "bold"}
text.format(0, 2, attrs)

Parameters:

  • index (Integer)
  • length (Integer)
  • attrs (Hash)


160
161
162
163
164
# File 'lib/y/text.rb', line 160

def format(index, length, attrs)
  document.current_transaction do |tx|
    ytext_format(tx, index, length, attrs)
  end
end

#insert(index, value, attrs = nil) ⇒ void

This method returns an undefined value.

Insert a value at position and with optional attributes. This method is similar to [String#insert](ruby-doc.org/core-3.1.2/String.html), except for the optional third ‘attrs` argument.

The value can be any of the supported types:

  • Boolean

  • String

  • Numeric

  • Array (where element types must be supported)

  • Hash (where the the types of key and values must be supported)

Examples:

Insert a string at position

doc = Y::Doc.new
text = doc.get_text("my text")
text << "Hello, "

text.insert(7, "World!")

puts text.to_s == "Hello, World!" # true

Parameters:

  • index (Integer)
  • value (String|Numeric|Array|Hash)
  • attrs (Hash|nil) (defaults to: nil)


122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/y/text.rb', line 122

def insert(index, value, attrs = nil)
  document.current_transaction do |tx|
    if value.is_a?(String)
      ytext_insert(tx, index, value) if attrs.nil?
      unless attrs.nil?
        ytext_insert_with_attributes(tx, index, value, attrs)
      end
      return nil
    end

    if can_insert?(value)
      ytext_insert_embed(tx, index, value) if attrs.nil?
      unless attrs.nil?
        ytext_insert_embed_with_attributes(tx, index, value, attrs)
      end
      return nil
    end

    raise ArgumentError,
          "Can't insert value. `#{value.class.name}` isn't supported."
  end
end

#lengthInteger Also known as: size

Returns length of text

Returns:

  • (Integer)

    Length of text



169
170
171
# File 'lib/y/text.rb', line 169

def length
  document.current_transaction { |tx| ytext_length(tx) }
end

#slice!(index) ⇒ void #slice!(start, length) ⇒ void #slice!(range) ⇒ void

This method returns an undefined value.

Removes a part from text

Attention: In comparison to String#slice, #slice! will not return the substring that gets removed. Even this being technically possible, it requires us to read the substring before removing it, which is not desirable in most situations.

Examples:

Removes a single character

doc = Y::Doc.new

text = doc.get_text("my text")
text << "Hello"

text.slice!(0)

text.to_s == "ello" # true

Removes a range of characters

doc = Y::Doc.new

text = doc.get_text("my text")
text << "Hello"

text.slice!(1..2)
text.to_s == "Hlo" # true

text.slice!(1...2)
text.to_s == "Ho" # true

Removes a range of chars from start and for given length

doc = Y::Doc.new

text = doc.get_text("my text")
text << "Hello"

text.slice!(0, 3)

text.to_s == "lo" # true

Overloads:

  • #slice!(index) ⇒ void

    Removes a single character at index

  • #slice!(start, length) ⇒ void

    Removes a range of characters

  • #slice!(range) ⇒ void

    Removes a range of characters



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/y/text.rb', line 226

def slice!(*args)
  document.current_transaction do |tx|
    if args.empty?
      raise ArgumentError,
            "Provide one of `index`, `range`, `start, length` as arguments"
    end

    if args.size == 1
      arg = args.first

      if arg.is_a?(Range)
        ytext_remove_range(tx, arg.first, arg.last - arg.first)
        return nil
      end

      if arg.is_a?(Numeric)
        ytext_remove_range(tx, arg.to_int, 1)
        return nil
      end
    end

    if args.size == 2
      start, length = args

      if start.is_a?(Numeric) && length.is_a?(Numeric)
        ytext_remove_range(tx, start, length)
        return nil
      end
    end

    raise ArgumentError, "Please check your arguments, can't slice."
  end
end

#to_sString

Returns string representation of text

Examples:

doc = Y::Doc.new
text = doc.get_text("my text")
text << "Hello"

puts text.to_s # "Hello"

Returns:

  • (String)


272
273
274
# File 'lib/y/text.rb', line 272

def to_s
  document.current_transaction { |tx| ytext_to_s(tx) }
end