pandocomatic 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a4eb96b887676605773e3929aebac5709f2a70ff
4
- data.tar.gz: 2815789aeb3065e128606f3dedb338277251134f
3
+ metadata.gz: 54aa9b0867deb75ba7418c9fd508e5081d3aadc3
4
+ data.tar.gz: 86f74230480873d24004306c5c446b7ff6a2648e
5
5
  SHA512:
6
- metadata.gz: 439b66fabcd4f8c9af43c112f16495aa251a71a592ba22b8691fbdfb40ced84dd1abdb859a927be56ad2fd829aede581a4f811749bdb58bcc9e0839a41ce9623
7
- data.tar.gz: 982c94db04f6e51e0bce760e3028aa8256bd9315d3b7ffab6bfe0609810479a215f7cc5ccb27df428fd0daffb4dd19d0cac76587741b0fcf6dda5a7fef99f78b
6
+ metadata.gz: 43f04725a6eb099b3d545cc9ac7da7435d9d2de923b2a91e46b842c6c5c710acd43cc37d98c957c0a25ab34f6ed36939438b36a94237b497a6a2310aeadafec4
7
+ data.tar.gz: d0c090612f6482cf293a29636f9bd8520504b063a6c01b03f0c08cb866a89e96d360ae09544a286c6df7f71d074b1862d06cb143c86bb8ef524df9fda742e09b
@@ -96,6 +96,10 @@ module Pandocomatic
96
96
  false
97
97
  end
98
98
 
99
+ def multiple?()
100
+ false
101
+ end
102
+
99
103
  def skip?()
100
104
  false
101
105
  end
@@ -23,12 +23,14 @@ module Pandocomatic
23
23
  require_relative 'command.rb'
24
24
  require_relative 'create_link_command.rb'
25
25
  require_relative 'convert_file_command.rb'
26
+ require_relative 'convert_list_command.rb'
27
+ require_relative 'convert_file_multiple_command.rb'
26
28
  require_relative 'copy_file_command.rb'
27
29
  require_relative 'skip_command.rb'
28
30
 
29
- class ConvertDirCommand < Command
31
+ class ConvertDirCommand < ConvertListCommand
30
32
 
31
- attr_reader :config, :src_dir, :dst_dir, :subcommands
33
+ attr_reader :config, :src_dir, :dst_dir
32
34
 
33
35
  def initialize(current_config, src_dir, dst_dir)
34
36
  super()
@@ -49,8 +51,6 @@ module Pandocomatic
49
51
  @errors.push IOError.new(:directory_is_not_a_directory, nil, @dst_dir) unless File.directory? @dst_dir
50
52
  end
51
53
 
52
- @subcommands = []
53
-
54
54
  Dir.foreach @src_dir do |filename|
55
55
  src = File.join @src_dir, filename
56
56
 
@@ -70,10 +70,7 @@ module Pandocomatic
70
70
  end
71
71
  elsif File.file? src
72
72
  if config.convert? src then
73
- dst = config.set_extension dst
74
- if not modified_only? or file_modified? src, dst then
75
- subcommand = ConvertFileCommand.new(config, src, dst)
76
- end
73
+ subcommand = ConvertFileMultipleCommand.new(config, src, dst)
77
74
  else
78
75
  if not modified_only? or file_modified? src, dst then
79
76
  subcommand = CopyFileCommand.new(src, dst)
@@ -83,7 +80,7 @@ module Pandocomatic
83
80
  subcommand = SkipCommand.new(src, :unclear_what_to_do)
84
81
  end
85
82
 
86
- @subcommands.push subcommand unless subcommand.nil? or subcommand.skip?
83
+ push subcommand unless subcommand.nil? or subcommand.skip?
87
84
  end
88
85
 
89
86
  # Empty commands do not count to the total amount of commands to execute
@@ -94,18 +91,6 @@ module Pandocomatic
94
91
  @subcommands.empty?
95
92
  end
96
93
 
97
- def count()
98
- @subcommands.reduce(if skip? then 0 else 1 end) do |total, subcommand|
99
- total += subcommand.count
100
- end
101
- end
102
-
103
- def all_errors()
104
- @subcommands.reduce(@errors) do |total, subcommand|
105
- total += subcommand.all_errors
106
- end
107
- end
108
-
109
94
  def directory?()
110
95
  true
111
96
  end
@@ -122,17 +107,6 @@ module Pandocomatic
122
107
  end
123
108
  end
124
109
 
125
- def execute()
126
- if not @subcommands.empty?
127
- CommandPrinter.new(self).print unless quiet?
128
- run if not dry_run? and runnable?
129
-
130
- @subcommands.each do |subcommand|
131
- subcommand.execute
132
- end
133
- end
134
- end
135
-
136
110
  private
137
111
 
138
112
  def create_directory?()
@@ -24,22 +24,32 @@ module Pandocomatic
24
24
  require_relative '../processor.rb'
25
25
  require_relative '../fileinfo_preprocessor'
26
26
 
27
+ require_relative '../configuration.rb'
28
+
27
29
  require_relative '../error/io_error.rb'
28
30
  require_relative '../error/configuration_error.rb'
29
31
  require_relative '../error/processor_error.rb'
30
32
 
31
33
  require_relative 'command.rb'
32
34
 
35
+ OUTPUT_FORMATS = ["docx", "odt", "pdf", "beamer"]
36
+
33
37
  class ConvertFileCommand < Command
34
38
 
35
39
  attr_reader :config, :src, :dst
36
40
 
37
- def initialize(config, src, dst)
41
+ def initialize(config, src, dst, template_name = nil)
38
42
  super()
39
43
  @config = config
40
44
  @src = src
41
45
  @dst = dst
42
46
 
47
+ if template_name.nil? or template_name.empty?
48
+ @template_name = @config.determine_template @src
49
+ else
50
+ @template_name = template_name
51
+ end
52
+
43
53
  @errors.push IOError.new(:file_does_not_exist, nil, @src) unless File.exist? @src
44
54
  @errors.push IOError.new(:file_is_not_a_file, nil, @src) unless File.file? @src
45
55
  @errors.push IOError.new(:file_is_not_readable, nil, @src) unless File.readable? @src
@@ -60,16 +70,9 @@ module Pandocomatic
60
70
  pandoc_options = metadata.pandoc_options || {}
61
71
  template = {}
62
72
 
63
- if metadata.has_template? then
64
- template_name = metadata.template_name
65
- else
66
- template_name = @config.determine_template @src
67
- end
68
-
69
- if not template_name.nil? and not template_name.empty?
70
- raise ConfigurationError.new(:no_such_template, nil, template_name) unless @config.has_template? template_name
71
-
72
- template = @config.get_template template_name
73
+ if not @template_name.nil? and not @template_name.empty?
74
+ raise ConfigurationError.new(:no_such_template, nil, @template_name) unless @config.has_template? @template_name
75
+ template = @config.get_template @template_name
73
76
 
74
77
  pandoc_options = (template['pandoc'] || {}).merge(pandoc_options) do |key, oldval, newval|
75
78
  # Options that can occur more than once, such as 'filter' or
@@ -94,11 +97,13 @@ module Pandocomatic
94
97
  end
95
98
 
96
99
  begin
97
- File.open(@dst, 'w') do |file|
98
- raise IOError.new(:file_is_not_a_file, nil, @dst) unless File.file? @dst
99
- raise IOError.new(:file_is_not_writable, nil, @dst) unless File.writable? @dst
100
- file << output
101
- end
100
+ unless OUTPUT_FORMATS.include? pandoc_options["to"] then
101
+ File.open(@dst, 'w') do |file|
102
+ raise IOError.new(:file_is_not_a_file, nil, @dst) unless File.file? @dst
103
+ raise IOError.new(:file_is_not_writable, nil, @dst) unless File.writable? @dst
104
+ file << output
105
+ end
106
+ end
102
107
  rescue StandardError => e
103
108
  raise IOError.new(:error_writing_file, e, @dst)
104
109
  end
@@ -125,18 +130,28 @@ module Pandocomatic
125
130
  def pandoc(input, options, src_dir)
126
131
  converter = Paru::Pandoc.new
127
132
  options.each do |option, value|
133
+ # Pandoc multi-word options can have the multiple words separated by
134
+ # both underscore (_) and dash (-).
135
+ option= option.gsub "-", "_"
136
+
128
137
  if PANDOC_OPTIONS_WITH_PATH.include? option
129
138
  if value.is_a? Array
130
- value = value.map {|v| @config.update_path v, src_dir}
139
+ value = value.map {|v| @config.update_path(v, src_dir, option == "filter")}
131
140
  else
132
- value = @config.update_path value, src_dir
141
+ value = @config.update_path(value, src_dir, option == "filter")
133
142
  end
134
143
  end
135
144
 
145
+ # There is no "pdf" output format; change it to latex but keep the
146
+ # extension.
147
+ value = "latex" if option == "to" and value == "pdf"
148
+
136
149
  converter.send option, value unless option == 'output'
137
150
  # don't let pandoc write the output to enable postprocessing
138
151
  end
139
152
 
153
+ converter.send "output", @dst if OUTPUT_FORMATS.include? options["to"]
154
+
140
155
  begin
141
156
  converter << input
142
157
  rescue Paru::Error => e
@@ -160,8 +175,13 @@ module Pandocomatic
160
175
  output = input
161
176
  processors.each do |processor|
162
177
  script = @config.update_path(processor, File.dirname(@src))
163
-
164
- raise ProcessorError.new(:script_does_not_exist, nil, script) unless File.exist? script
178
+
179
+ if not File.exists? script
180
+ script = Configuration.which(script)
181
+
182
+ raise ProcessorError.new(:script_does_not_exist, nil, script) if script.nil?
183
+ end
184
+
165
185
  raise ProcessorError.new(:script_is_not_executable, nil, script) unless File.executable? script
166
186
 
167
187
  begin
@@ -175,6 +195,5 @@ module Pandocomatic
175
195
  input
176
196
  end
177
197
  end
178
-
179
198
  end
180
199
  end
@@ -0,0 +1,87 @@
1
+ #--
2
+ # Copyright 2017, Huub de Beer <Huub@heerdebeer.org>
3
+ #
4
+ # This file is part of pandocomatic.
5
+ #
6
+ # Pandocomatic is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by the
8
+ # Free Software Foundation, either version 3 of the License, or (at your
9
+ # option) any later version.
10
+ #
11
+ # Pandocomatic is distributed in the hope that it will be useful, but
12
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
+ # for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License along
17
+ # with pandocomatic. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+ module Pandocomatic
20
+
21
+ require_relative '../error/io_error.rb'
22
+
23
+ require_relative 'command.rb'
24
+ require_relative 'create_link_command.rb'
25
+ require_relative 'convert_file_command.rb'
26
+ require_relative 'convert_list_command.rb'
27
+ require_relative 'copy_file_command.rb'
28
+ require_relative 'skip_command.rb'
29
+
30
+ class ConvertFileMultipleCommand < ConvertListCommand
31
+
32
+ attr_reader :subcommands
33
+
34
+ def initialize(config, src, dst)
35
+ super()
36
+ @config = config
37
+ @src = src
38
+
39
+ metadata = PandocMetadata.load_file @src
40
+ metadata.templates.each do |template_name|
41
+ raise ConfigurationError.new(:no_such_template, nil, template_name) unless template_name.empty? or config.has_template? template_name
42
+
43
+ dst = config.set_extension dst, template_name, metadata
44
+ if not modified_only? or file_modified? @src, dst then
45
+ subcommand = ConvertFileCommand.new(@config, @src, dst, template_name)
46
+ push subcommand unless subcommand.nil? or subcommand.skip?
47
+ end
48
+ end
49
+ end
50
+
51
+ def push(command)
52
+ @subcommands.push command
53
+ end
54
+
55
+ def skip?()
56
+ @subcommands.empty?
57
+ end
58
+
59
+ def count()
60
+ @subcommands.reduce(if skip? then 0 else 1 end) do |total, subcommand|
61
+ total += subcommand.count
62
+ end
63
+ end
64
+
65
+ def all_errors()
66
+ @subcommands.reduce(@errors) do |total, subcommand|
67
+ total += subcommand.all_errors
68
+ end
69
+ end
70
+
71
+ def to_s()
72
+ "converting #{@src} #{@subcommands.size} time#{'s' if @subcommands.size != 1}:"
73
+ end
74
+
75
+ def execute()
76
+ if not @subcommands.empty?
77
+ CommandPrinter.new(self).print unless quiet? or @subcommands.size == 1
78
+ run if not dry_run? and runnable?
79
+
80
+ @subcommands.each do |subcommand|
81
+ subcommand.execute
82
+ end
83
+ end
84
+ end
85
+
86
+ end
87
+ end
@@ -0,0 +1,78 @@
1
+ #--
2
+ # Copyright 2017, Huub de Beer <Huub@heerdebeer.org>
3
+ #
4
+ # This file is part of pandocomatic.
5
+ #
6
+ # Pandocomatic is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by the
8
+ # Free Software Foundation, either version 3 of the License, or (at your
9
+ # option) any later version.
10
+ #
11
+ # Pandocomatic is distributed in the hope that it will be useful, but
12
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
+ # for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License along
17
+ # with pandocomatic. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+ module Pandocomatic
20
+
21
+ require_relative '../error/io_error.rb'
22
+
23
+ require_relative 'command.rb'
24
+ require_relative 'create_link_command.rb'
25
+ require_relative 'convert_file_command.rb'
26
+ require_relative 'copy_file_command.rb'
27
+ require_relative 'skip_command.rb'
28
+
29
+ class ConvertListCommand < Command
30
+
31
+ attr_reader :subcommands
32
+
33
+ def initialize()
34
+ super()
35
+ @subcommands = []
36
+ end
37
+
38
+ def push(command)
39
+ @subcommands.push command
40
+ end
41
+
42
+ def skip?()
43
+ @subcommands.empty?
44
+ end
45
+
46
+ def count()
47
+ @subcommands.reduce(if skip? then 0 else 1 end) do |total, subcommand|
48
+ total += subcommand.count
49
+ end
50
+ end
51
+
52
+ def all_errors()
53
+ @subcommands.reduce(@errors) do |total, subcommand|
54
+ total += subcommand.all_errors
55
+ end
56
+ end
57
+
58
+ def to_s()
59
+ "converting #{@subcommands.size} items:"
60
+ end
61
+
62
+ def multiple?
63
+ true
64
+ end
65
+
66
+ def execute()
67
+ if not @subcommands.empty?
68
+ CommandPrinter.new(self).print unless quiet?
69
+ run if not dry_run? and runnable?
70
+
71
+ @subcommands.each do |subcommand|
72
+ subcommand.execute
73
+ end
74
+ end
75
+ end
76
+
77
+ end
78
+ end
@@ -139,22 +139,38 @@ module Pandocomatic
139
139
  @settings['follow_links']
140
140
  end
141
141
 
142
- def set_extension(dst)
142
+ def set_extension(dst, template_name, metadata)
143
143
  dir = File.dirname dst
144
144
  ext = File.extname dst
145
145
  basename = File.basename dst, ext
146
- File.join dir, "#{basename}.#{find_extension dst}"
146
+ File.join dir, "#{basename}.#{find_extension(dst, template_name, metadata)}"
147
147
  end
148
148
 
149
- def find_extension(dst)
150
- template = determine_template dst
151
- if template.nil? then
152
- extension = 'html'
149
+ def find_extension(dst, template_name, metadata)
150
+ extension = "html"
151
+ if template_name.nil? or template_name.empty? then
152
+ if metadata.has_pandocomatic?
153
+ pandocomatic = metadata.pandocomatic
154
+ if pandocomatic.has_key? "pandoc"
155
+ pandoc = pandocomatic["pandoc"]
156
+
157
+ if pandoc.has_key? "to"
158
+ extension = pandoc["to"]
159
+ end
160
+ end
161
+ end
153
162
  else
154
163
  # TODO: what if there is no pandoc.to?
155
- to = @templates[template]['pandoc']['to']
156
- extension = FORMAT_TO_EXT[to] || to
164
+ if @templates[template_name].has_key? "pandoc"
165
+ pandoc = @templates[template_name]["pandoc"]
166
+ if pandoc.has_key? "to"
167
+ extension = pandoc["to"]
168
+ end
169
+ end
157
170
  end
171
+
172
+ extension = FORMAT_TO_EXT[extension] || extension
173
+ return extension
158
174
  end
159
175
 
160
176
  def has_template?(template_name)
@@ -171,16 +187,23 @@ module Pandocomatic
171
187
  end.keys.first
172
188
  end
173
189
 
174
- def update_path(path, src_dir)
190
+ def update_path(path, src_dir, check_executable = false)
191
+ updated_path = path
175
192
  if path.start_with? './'
176
193
  # refers to a local (to file) dir
177
- File.join src_dir, path
178
- elsif path.start_with? '/' then
179
- path
194
+ updated_path = File.join src_dir, path
180
195
  else
181
- # refers to data-dir
182
- File.join @data_dir, path
196
+ if check_executable
197
+ updated_path = Configuration.which path
198
+ end
199
+
200
+ if not updated_path.start_with? '/' then
201
+ # refers to data-dir
202
+ updated_path = File.join @data_dir, updated_path
203
+ end
183
204
  end
205
+
206
+ updated_path
184
207
  end
185
208
 
186
209
  private
@@ -234,6 +257,24 @@ module Pandocomatic
234
257
  end
235
258
  end
236
259
 
260
+ # Cross-platform way of finding an executable in the $PATH.
261
+ #
262
+ # which('ruby') #=> /usr/bin/ruby
263
+ #
264
+ # Taken from:
265
+ # http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby#5471032
266
+ def self.which(cmd)
267
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
268
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
269
+ exts.each { |ext|
270
+ exe = File.join(path, "#{cmd}#{ext}")
271
+ return exe if File.executable?(exe) &&
272
+ !File.directory?(exe)
273
+ }
274
+ end
275
+ return nil
276
+ end
277
+
237
278
  end
238
279
 
239
280
  end
@@ -37,7 +37,7 @@ module Pandocomatic
37
37
 
38
38
  def self.pandoc2yaml(input)
39
39
  input
40
- .scan(/^---\n(.+?)^(?:---|\.\.\.)\n/m)
40
+ .scan(/^---[ \t]*\n(.+?)^(?:---|\.\.\.)[ \t]*\n/m)
41
41
  .flatten
42
42
  .map{|yaml| yaml.strip}
43
43
  .join("\n")
@@ -63,6 +63,18 @@ module Pandocomatic
63
63
  has_pandocomatic? and pandocomatic.has_key? 'use-template' and not pandocomatic['use-template'].empty?
64
64
  end
65
65
 
66
+ def templates()
67
+ if has_template?
68
+ if pandocomatic['use-template'].is_a? Array
69
+ pandocomatic['use-template']
70
+ else
71
+ [pandocomatic['use-template']]
72
+ end
73
+ else
74
+ [""]
75
+ end
76
+ end
77
+
66
78
  def template_name()
67
79
  if has_template? then
68
80
  pandocomatic['use-template']
@@ -87,7 +99,12 @@ module Pandocomatic
87
99
  end
88
100
 
89
101
  def has_pandocomatic?()
90
- has_key? 'pandocomatic' or has_key? 'pandocomatic_'
102
+ config = nil
103
+ if has_key? 'pandocomatic' or has_key? 'pandocomatic_'
104
+ config = self['pandocomatic'] if has_key? 'pandocomatic'
105
+ config = self['pandocomatic_'] if has_key? 'pandocomatic_'
106
+ end
107
+ config.is_a? Hash
91
108
  end
92
109
 
93
110
  def pandocomatic()
@@ -37,7 +37,9 @@ module Pandocomatic
37
37
 
38
38
  require_relative './command/command.rb'
39
39
  require_relative './command/convert_dir_command.rb'
40
+ require_relative './command/convert_list_command.rb'
40
41
  require_relative './command/convert_file_command.rb'
42
+ require_relative './command/convert_file_multiple_command.rb'
41
43
 
42
44
  class Pandocomatic
43
45
  VERSION = [0, 1, 2]
@@ -79,8 +81,10 @@ module Pandocomatic
79
81
  if File.directory? input
80
82
  command = ConvertDirCommand.new(configuration, input, output)
81
83
  else
82
- command = ConvertFileCommand.new(configuration, input, output)
83
- command.make_quiet
84
+ destination = if output.nil? or output.empty? then File.basename input else output end
85
+
86
+ command = ConvertFileMultipleCommand.new(configuration, input, destination)
87
+ command.make_quiet unless command.subcommands.size > 1
84
88
  end
85
89
 
86
90
  # Notify the user about all configuration errors collected when
@@ -1 +1 @@
1
- (<%=@command.index_to_s%>) <%=if @command.directory? then "+ " else " - " end%><%= @command.to_s%>
1
+ (<%=@command.index_to_s%>) <%=if @command.multiple? then "+ " else " - " end%><%= @command.to_s%>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pandocomatic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Huub de Beer
@@ -91,6 +91,8 @@ files:
91
91
  - lib/pandocomatic/command/command.rb
92
92
  - lib/pandocomatic/command/convert_dir_command.rb
93
93
  - lib/pandocomatic/command/convert_file_command.rb
94
+ - lib/pandocomatic/command/convert_file_multiple_command.rb
95
+ - lib/pandocomatic/command/convert_list_command.rb
94
96
  - lib/pandocomatic/command/copy_file_command.rb
95
97
  - lib/pandocomatic/command/create_link_command.rb
96
98
  - lib/pandocomatic/command/skip_command.rb
@@ -150,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
152
  requirements:
151
153
  - pandoc, a universal document converer <http://pandoc.org>
152
154
  rubyforge_project:
153
- rubygems_version: 2.5.1
155
+ rubygems_version: 2.5.2
154
156
  signing_key:
155
157
  specification_version: 4
156
158
  summary: Automating the use of pandoc