konjac 0.2.9.5 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/konjac.gemspec +1 -0
- data/lib/konjac.rb +0 -3
- data/lib/konjac/cli.rb +2 -2
- data/lib/konjac/exception.rb +3 -0
- data/lib/konjac/office.rb +64 -257
- data/lib/konjac/office/generic.rb +76 -0
- data/lib/konjac/office/mac.rb +11 -0
- data/lib/konjac/office/mac/excel.rb +73 -0
- data/lib/konjac/office/mac/power_point.rb +68 -0
- data/lib/konjac/office/mac/shared.rb +36 -0
- data/lib/konjac/office/mac/word.rb +114 -0
- data/lib/konjac/office/os.rb +53 -0
- data/lib/konjac/office/tag.rb +91 -0
- data/lib/konjac/office/windows.rb +11 -0
- data/lib/konjac/office/windows/excel.rb +0 -0
- data/lib/konjac/office/windows/power_point.rb +0 -0
- data/lib/konjac/office/windows/shared.rb +2 -0
- data/lib/konjac/office/windows/word.rb +0 -0
- data/lib/konjac/office/xml.rb +11 -0
- data/lib/konjac/office/xml/shared.rb +262 -0
- data/lib/konjac/version.rb +1 -1
- data/lib/locales/en.yml +1 -0
- data/lib/locales/ja.yml +1 -0
- data/spec/office/generic_spec.rb +72 -0
- data/spec/office_spec.rb +37 -0
- metadata +58 -39
- data/lib/applescripts/konjac_excel_export +0 -120
- data/lib/applescripts/konjac_excel_import +0 -112
- data/lib/applescripts/konjac_powerpoint_export +0 -116
- data/lib/applescripts/konjac_powerpoint_import +0 -109
- data/lib/applescripts/konjac_word_export +0 -110
- data/lib/applescripts/konjac_word_import +0 -139
- data/lib/konjac/os.rb +0 -51
- data/lib/konjac/tag.rb +0 -50
- data/lib/konjac/tag_manager.rb +0 -65
- data/spec/tag_spec.rb +0 -63
@@ -0,0 +1,11 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module Konjac
|
3
|
+
module Office
|
4
|
+
module Mac
|
5
|
+
autoload :Excel, "konjac/office/mac/excel"
|
6
|
+
autoload :PowerPoint, "konjac/office/mac/power_point"
|
7
|
+
autoload :Shared, "konjac/office/mac/shared"
|
8
|
+
autoload :Word, "konjac/office/mac/word"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module Konjac
|
3
|
+
module Office
|
4
|
+
module Mac
|
5
|
+
class Excel < Shared
|
6
|
+
def initialize(path = nil)
|
7
|
+
super "Microsoft Excel", path
|
8
|
+
@strippable = //
|
9
|
+
@delimiter = "\r"
|
10
|
+
@parse_order = [:sheet, :row, :cell]
|
11
|
+
find 1, 1, 1
|
12
|
+
end
|
13
|
+
|
14
|
+
# Retrieves the active document and caches it
|
15
|
+
def active_document
|
16
|
+
@active_document ||= @application.active_workbook
|
17
|
+
end
|
18
|
+
|
19
|
+
def write(text, *args)
|
20
|
+
if args.empty?
|
21
|
+
@current.formula.set text
|
22
|
+
else
|
23
|
+
opts = parse_args(*args)
|
24
|
+
@document.sheets[opts[:sheet]]
|
25
|
+
.rows[opts[:row]]
|
26
|
+
.cells[opts[:cell]].formula.set text
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Creates a dump of the spreadsheet's data in Tag form
|
31
|
+
def data
|
32
|
+
tags = []
|
33
|
+
@document.sheets.get.each_with_index do |sheet, s|
|
34
|
+
sheet.used_range.rows.get.each_with_index do |row, r|
|
35
|
+
row.cells.get.each_with_index do |cell, c|
|
36
|
+
temp = Tag.new
|
37
|
+
temp.indices = [s + 1, r + 1, c + 1]
|
38
|
+
temp.removed = temp.added = read(s + 1, r + 1, c + 1)
|
39
|
+
tags << temp unless temp.blank?
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
tags
|
44
|
+
end
|
45
|
+
|
46
|
+
# Finds the paragraph indicated by the provided index
|
47
|
+
def find(*args)
|
48
|
+
unless args.empty?
|
49
|
+
@indices = args
|
50
|
+
opts = parse_args(*args)
|
51
|
+
@current = @document.sheets[opts[:sheet]]
|
52
|
+
.rows[opts[:row]]
|
53
|
+
.cells[opts[:cell]]
|
54
|
+
end
|
55
|
+
|
56
|
+
@current.formula.get
|
57
|
+
end
|
58
|
+
|
59
|
+
# Retrieves the number of cells in the document. Note that this method
|
60
|
+
# fetches all row and column elements and can thus be very expensive for
|
61
|
+
# large spreadsheets.
|
62
|
+
def size
|
63
|
+
@document.sheets.inject(0) do |result, sheet|
|
64
|
+
range = sheet.used_range
|
65
|
+
result += range.rows.get.size * range.columns.get.size
|
66
|
+
end
|
67
|
+
end
|
68
|
+
alias :length :size
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module Konjac
|
3
|
+
module Office
|
4
|
+
module Mac
|
5
|
+
class PowerPoint < Shared
|
6
|
+
def initialize(path = nil)
|
7
|
+
super "Microsoft PowerPoint", path
|
8
|
+
@strippable = //
|
9
|
+
@delimiter = "\r"
|
10
|
+
@parse_order = [:slide, :shape]
|
11
|
+
find 1, 1
|
12
|
+
end
|
13
|
+
|
14
|
+
# Retrieves the active document and caches it
|
15
|
+
def active_document
|
16
|
+
@active_document ||= @application.active_presentation
|
17
|
+
end
|
18
|
+
|
19
|
+
def write(text, *args)
|
20
|
+
if args.empty?
|
21
|
+
@current.text_frame.text_range.content.set text
|
22
|
+
else
|
23
|
+
opts = parse_args(*args)
|
24
|
+
@document.slides[opts[:slide]]
|
25
|
+
.shapes[opts[:shape]].text_frame.text_range.content.set text
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Creates a dump of the spreadsheet's data in Tag form
|
30
|
+
def data
|
31
|
+
tags = []
|
32
|
+
@document.slides.get.each_with_index do |slide, sl|
|
33
|
+
slide.shapes.get.each_with_index do |shape, sh|
|
34
|
+
temp = Tag.new
|
35
|
+
temp.indices = [sl + 1, sh + 1]
|
36
|
+
temp.removed = temp.added = read(sl + 1, sh + 1)
|
37
|
+
tags << temp unless temp.blank?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
tags
|
41
|
+
end
|
42
|
+
|
43
|
+
# Finds the paragraph indicated by the provided index
|
44
|
+
def find(*args)
|
45
|
+
unless args.empty?
|
46
|
+
@indices = args
|
47
|
+
opts = parse_args(*args)
|
48
|
+
@current = @document.slides[opts[:slide]]
|
49
|
+
.shapes[opts[:shape]]
|
50
|
+
end
|
51
|
+
|
52
|
+
@current.text_frame.text_range.content.get
|
53
|
+
end
|
54
|
+
|
55
|
+
# Retrieves the number of cells in the document. Note that this method
|
56
|
+
# fetches all row and column elements and can thus be very expensive for
|
57
|
+
# large spreadsheets.
|
58
|
+
def size
|
59
|
+
end
|
60
|
+
alias :length :size
|
61
|
+
|
62
|
+
def delimiter(type = nil)
|
63
|
+
"\r"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require "appscript"
|
3
|
+
|
4
|
+
module Konjac
|
5
|
+
module Office
|
6
|
+
module Mac
|
7
|
+
class Shared < Generic
|
8
|
+
def initialize(app_name, path = nil)
|
9
|
+
@application = Appscript.app(app_name)
|
10
|
+
super path
|
11
|
+
end
|
12
|
+
|
13
|
+
def open(path)
|
14
|
+
@application.open path
|
15
|
+
end
|
16
|
+
|
17
|
+
# Retrieves the POSIX path of the document
|
18
|
+
def path
|
19
|
+
@path ||= posix_path(@document.full_name.get)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# Converts an HFS (Mac) path to a POSIX path
|
25
|
+
def posix_path(hfs_path)
|
26
|
+
%x[osascript -e 'POSIX path of "#{hfs_path}"'].chomp
|
27
|
+
end
|
28
|
+
|
29
|
+
# Converts a POSIX path to an HFS (Mac) path
|
30
|
+
def hfs_path(posix_path)
|
31
|
+
%x[osascript -e '(POSIX file "#{posix_path}") as string'].chomp
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module Konjac
|
3
|
+
module Office
|
4
|
+
module Mac
|
5
|
+
class Word < Shared
|
6
|
+
def initialize(path = nil)
|
7
|
+
super "Microsoft Word", path
|
8
|
+
@strippable = /[\r\n\a]+$/
|
9
|
+
@index = 1
|
10
|
+
@current = @document.paragraphs[@index]
|
11
|
+
@parse_order = [:paragraph]
|
12
|
+
end
|
13
|
+
|
14
|
+
# Retrieves the active document and caches it
|
15
|
+
def active_document
|
16
|
+
@active_document ||= @application.active_document
|
17
|
+
end
|
18
|
+
|
19
|
+
def write(text, *args)
|
20
|
+
opts = super(text, *args)
|
21
|
+
if opts[:type].nil? || opts[:type].empty?
|
22
|
+
select opts
|
23
|
+
@application.selection.type_text :text => text
|
24
|
+
else
|
25
|
+
@document.shapes[opts[:paragraph]].text_frame.text_range.content.set text
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Creates a dump of the document's data in Tag form
|
30
|
+
def data
|
31
|
+
@index = 1
|
32
|
+
@current = @document.paragraphs[@index]
|
33
|
+
|
34
|
+
tags = []
|
35
|
+
|
36
|
+
# An open-ended loop is necessary because requesting a paragraphs
|
37
|
+
# enumerator will retrieve all paragraphs from the document,
|
38
|
+
# potentially consuming a large amount of memory and freezing Word
|
39
|
+
loop do
|
40
|
+
temp = Tag.new
|
41
|
+
temp.indices = [@index]
|
42
|
+
temp.removed = temp.added = read
|
43
|
+
tags << temp unless temp.blank?
|
44
|
+
break if succ.nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
# TODO: I should optimize this later like above, to prevent large
|
48
|
+
# shapes from getting out of hand
|
49
|
+
@document.shapes.get.each_with_index do |shape, index|
|
50
|
+
temp = Tag.new
|
51
|
+
temp.indices = [index + 1]
|
52
|
+
temp.removed = temp.added =
|
53
|
+
clean(shape.text_frame.text_range.content.get)
|
54
|
+
temp.type = :shape
|
55
|
+
tags << temp unless temp.blank?
|
56
|
+
end
|
57
|
+
|
58
|
+
tags
|
59
|
+
end
|
60
|
+
|
61
|
+
# Finds the paragraph indicated by the provided index
|
62
|
+
def find(*args)
|
63
|
+
unless args.empty? || args.nil?
|
64
|
+
opts = parse_args(*args)
|
65
|
+
if (opts[:type].nil? || opts[:type].empty?) && !opts[:paragraph].nil?
|
66
|
+
@index = opts[:paragraph]
|
67
|
+
@current = @document.paragraphs[opts[:paragraph]]
|
68
|
+
elsif opts[:type] == :shape
|
69
|
+
return @document.shapes[opts[:paragraph]].text_frame.text_range.content.get
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
@current.text_object.content.get
|
74
|
+
end
|
75
|
+
|
76
|
+
# Retrieves the number of paragraphs in the document. Note that this
|
77
|
+
# method fetches all paragraphs elements and can thus be very expensive
|
78
|
+
# for large documents.
|
79
|
+
def size
|
80
|
+
@document.paragraphs.get.size
|
81
|
+
end
|
82
|
+
alias :length :size
|
83
|
+
|
84
|
+
# Goes to the next paragraph
|
85
|
+
def succ
|
86
|
+
@index += 1
|
87
|
+
@current = @current.next_paragraph
|
88
|
+
rescue
|
89
|
+
@index -= 1
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
alias :next :succ
|
93
|
+
|
94
|
+
# Selects the paragraph indicated by an indicated, or +nil+ to select
|
95
|
+
# the current paragraph
|
96
|
+
def select(*args)
|
97
|
+
opts = parse_args(*args)
|
98
|
+
find opts
|
99
|
+
para_start = @current.text_object.start_of_content.get
|
100
|
+
para_end = @current.text_object.end_of_content.get
|
101
|
+
range = active_document.create_range(:start => para_start,
|
102
|
+
:end_ => para_end)
|
103
|
+
|
104
|
+
# Move in end of range by length of stripped content less end of table
|
105
|
+
# mark
|
106
|
+
strip_size = range.content.get[@strippable].gsub(/\a/, "").size
|
107
|
+
range = active_document.create_range(:start => para_start,
|
108
|
+
:end_ => para_end - strip_size)
|
109
|
+
range.select
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Konjac
|
2
|
+
module Office
|
3
|
+
# A module for determining what OS we're using
|
4
|
+
module OS
|
5
|
+
class << self
|
6
|
+
# Override string output
|
7
|
+
def to_s
|
8
|
+
RbConfig::CONFIG["host_os"]
|
9
|
+
end
|
10
|
+
|
11
|
+
# OS is a version of Mac
|
12
|
+
def mac?
|
13
|
+
@mac ||= is? /mac|darwin/
|
14
|
+
end
|
15
|
+
|
16
|
+
# OS is a version of Linux
|
17
|
+
def linux?
|
18
|
+
@linux ||= is? /linux|cygwin/
|
19
|
+
end
|
20
|
+
|
21
|
+
# OS is a version of Windows
|
22
|
+
def windows?
|
23
|
+
@windows ||= is? /mswin|^win|mingw/
|
24
|
+
end
|
25
|
+
|
26
|
+
# OS is POSIX (well, actually, this makes the somewhat bad assumption
|
27
|
+
# that non-Windows OSes are POSIX)
|
28
|
+
def posix?
|
29
|
+
!windows?
|
30
|
+
end
|
31
|
+
|
32
|
+
# Throws a message if the computer is using a command restricted to Macs
|
33
|
+
def not_a_mac
|
34
|
+
if mac?
|
35
|
+
return false
|
36
|
+
else
|
37
|
+
puts I18n.t(:mac_only)
|
38
|
+
return true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Test whether the +host_os+ configuration parameter matches a specified
|
46
|
+
# regular expression
|
47
|
+
def is?(match)
|
48
|
+
match === RbConfig::CONFIG["host_os"]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module Konjac
|
3
|
+
module Office
|
4
|
+
class Tag
|
5
|
+
attr_accessor :indices, :removed, :added, :type
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@indices = nil
|
9
|
+
@removed = []
|
10
|
+
@added = []
|
11
|
+
@type = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
# Whether the tag has changed content
|
15
|
+
def changed?
|
16
|
+
@removed != @added
|
17
|
+
end
|
18
|
+
|
19
|
+
# Determines whether the tag is blank, that is, if it has no +indices+ or
|
20
|
+
# both +removed+ and +added+ are empty
|
21
|
+
def blank?
|
22
|
+
@indices.nil? || (@removed.join.empty? && @added.join.empty?)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Converts the tag to a string
|
26
|
+
def to_s
|
27
|
+
<<-eos
|
28
|
+
@@ #{@type.nil? ? "" : "#{@type} "}#{@indices.join(",")} @@
|
29
|
+
-#{@removed.join("\n-")}
|
30
|
+
+#{@added.join("\n+")}
|
31
|
+
eos
|
32
|
+
end
|
33
|
+
|
34
|
+
# Whether the tag's content if for the default kind of object
|
35
|
+
def default?
|
36
|
+
@type.nil?
|
37
|
+
end
|
38
|
+
|
39
|
+
# Whether the tag's content if for a special kind of object
|
40
|
+
def special?
|
41
|
+
!!@type
|
42
|
+
end
|
43
|
+
|
44
|
+
class << self
|
45
|
+
TAG_MATCHES = {
|
46
|
+
:header => /^(?:---|\+\+\+)/,
|
47
|
+
:comment => /^\@\@ ([a-z]*) ?([\d, ]+) \@\@$/i,
|
48
|
+
:removed => /^-(.*)/,
|
49
|
+
:added => /^\+(.*)/,
|
50
|
+
}
|
51
|
+
|
52
|
+
# Loads the tags for the specified document path or the tags file itself
|
53
|
+
def load(path)
|
54
|
+
tags = []
|
55
|
+
temp = Tag.new
|
56
|
+
File.read("#{path.sub(/\.diff$/, "")}.diff").each_line do |line|
|
57
|
+
case line
|
58
|
+
when TAG_MATCHES[:header]
|
59
|
+
when TAG_MATCHES[:comment]
|
60
|
+
unless temp.blank?
|
61
|
+
tags << temp
|
62
|
+
temp = Tag.new
|
63
|
+
end
|
64
|
+
temp.type = $1.to_sym unless $1.nil?
|
65
|
+
temp.indices = $2.scan(/\d+/).map(&:to_i) # this changes $~
|
66
|
+
when TAG_MATCHES[:removed]
|
67
|
+
temp.removed << $1
|
68
|
+
when TAG_MATCHES[:added]
|
69
|
+
temp.added << $1
|
70
|
+
end
|
71
|
+
end
|
72
|
+
tags << temp unless temp.blank?
|
73
|
+
tags
|
74
|
+
end
|
75
|
+
|
76
|
+
def dump(tags, path, opts = {})
|
77
|
+
original_path = path.sub(/\.diff$/, "")
|
78
|
+
diff_path = "#{original_path}.diff"
|
79
|
+
|
80
|
+
File.open(diff_path, "w") do |file|
|
81
|
+
file.puts "--- #{original_path}"
|
82
|
+
file.puts "+++ #{original_path}"
|
83
|
+
tags.each do |tag|
|
84
|
+
file.puts tag.to_s
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|