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

#diffObject

Diff

@return[Array]



86
87
88
89
90
# File 'lib/y/text.rb', line 86

def diff
  document.current_transaction do |tx|
    ytext_diff(tx)
  end
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)


101
102
103
# File 'lib/y/text.rb', line 101

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)


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

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, 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)


131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/y/text.rb', line 131

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



178
179
180
# File 'lib/y/text.rb', line 178

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



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/y/text.rb', line 235

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)


281
282
283
# File 'lib/y/text.rb', line 281

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