konjac 0.2.9.5 → 0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|