Class: DocRipper::Formats::SketchRipper

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

Defined Under Namespace

Classes: Sqlite3NotFound

Instance Attribute Summary

Attributes inherited from Ripper::Base

#file_path

Instance Method Summary collapse

Methods inherited from Ripper::Base

#text

Constructor Details

#initialize(file_path) ⇒ SketchRipper

Returns a new instance of SketchRipper.

Raises:



49
50
51
52
# File 'lib/doc_ripper/formats/sketch_ripper.rb', line 49

def initialize(file_path)
  raise Sqlite3NotFound if !defined?(SQLite3)
  super
end

Instance Method Details

#blacklistObject



60
61
62
# File 'lib/doc_ripper/formats/sketch_ripper.rb', line 60

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

#ripObject



54
55
56
57
58
# File 'lib/doc_ripper/formats/sketch_ripper.rb', line 54

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



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/doc_ripper/formats/sketch_ripper.rb', line 64

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