Class: DocRipper::Formats::SketchRipper

Inherits:
Ripper::Base show all
Defined in:
lib/doc_ripper/formats/sketch_ripper.rb

Instance Attribute Summary

Attributes inherited from Ripper::Base

#text

Instance Method Summary collapse

Methods inherited from Ripper::Base

#initialize

Constructor Details

This class inherits a constructor from DocRipper::Ripper::Base

Instance Method Details

#blacklistObject



46
47
48
# File 'lib/doc_ripper/formats/sketch_ripper.rb', line 46

def blacklist
  %w(\$null MSAttributedStringFontAttribute NSColor NSParagraphStyle)
end

#read_typeObject



36
37
38
# File 'lib/doc_ripper/formats/sketch_ripper.rb', line 36

def read_type
  :mem
end

#ripObject



40
41
42
43
44
# File 'lib/doc_ripper/formats/sketch_ripper.rb', line 40

def rip
  db = SQLite3::Database.new(@file_path)
  data = db.execute("SELECT value FROM payload").flatten.first
  @text ||= text_objects(data).join(" ").strip
end

#text_objects(data) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/doc_ripper/formats/sketch_ripper.rb', line 50

def text_objects(data)
  objects = CFPropertyList::List.new(data: data).value.value['$objects'].value

  evaluator = Proc.new do |object, previous_object, n_2_previous_object, next_object|
    coordinatesRegex = /\{\{\d*, \d*}, \{\d*, \d*\}\}|\{[\d.e-]*, [\d.]*\}/

    object.is_a?(CFPropertyList::CFString) &&
      #ignore other blacklisted properties
      blacklist.select { |bl| object.value.match(/#{bl}/) }.empty? &&
      #ignore uuids
      !object.value.match(/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/) &&
      #ignore coordinates
      !object.value.match(coordinatesRegex) &&
      #ignore font definitions
      previous_object.value != "NSFontNameAttribute" &&
      # labels always have an dictionary defined afterwards
      next_object.is_a?(CFPropertyList::CFDictionary) &&
      # Check if the string is defining the name of an artboard or font
      !(previous_object.respond_to?(:blacklisted_class?) && previous_object.blacklisted_class?) &&
      !(n_2_previous_object.respond_to?(:blacklisted_class?) && n_2_previous_object.blacklisted_class?)
    end

  objects.select.with_index do |object,i|
    next_object = objects[i+1]
    previous_object = objects[i-1]
    n_2_previous_object = objects[i-2]

    evaluator.call(object, previous_object, n_2_previous_object, next_object)
  end
end