pandocomatic 0.1.4.9 → 0.1.4.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b790fdc99211b28030f3e6c2fb83ec9a68dcbf2c
4
- data.tar.gz: b3bce488828fd3f610b922d012022b9fa2c880ff
3
+ metadata.gz: 11bf26bcbf6d79b0583eca48c30e1b685314f514
4
+ data.tar.gz: c26dd9a4433581a6154df33096d993fe56208338
5
5
  SHA512:
6
- metadata.gz: daa6fea415f430f87d4806e15d405a8b2bd469005eec21530c1799ccde8dc19736ff8af34559a0d91e1ef6f9814531193301697c8f209bbb75dcd1f655672ac3
7
- data.tar.gz: cd9553189cb5f60350073d79192980e5ed4d205df5f79cf87a582f1bf6177b91fa875e535e6d05a722e80de93aa2ab6bca704c5e705773214bf693d4c9553a58
6
+ metadata.gz: 5b1d7bcd5051193689a09812c45a7e4155d06e47ca9d6906b5d02ba0dbb628cdaa952ae613206b1eb59d3dfc3f21a81c102006743cc53895cc0b51500a078d9a
7
+ data.tar.gz: cc8a459844153351c30749c2d0ff215ec8ff64655661b74f893acffcd7ecf1fba447d7d063a399dbf43a89b94862cd964b6e2c52c3ebc50c6872b672472ea8b1
@@ -18,271 +18,415 @@
18
18
  #++
19
19
  module Pandocomatic
20
20
 
21
- require 'yaml'
22
- require 'paru/pandoc'
21
+ require 'yaml'
22
+ require 'paru/pandoc'
23
+
24
+ # The default configuration for pandocomatic is read from
25
+ # default_configuration.yaml.
26
+ DEFAULT_CONFIG = YAML.load_file File.join(__dir__, 'default_configuration.yaml')
27
+
28
+ # Maps pandoc output formats to an extension.
29
+ FORMAT_TO_EXT = {
30
+ 'native' => 'hs',
31
+ 'markdown' => 'md',
32
+ 'markdown_strict' => 'md',
33
+ 'markdown_phpextra' => 'md',
34
+ 'markdown_github' => 'md',
35
+ 'html5' => 'html',
36
+ 'docx' => 'docx',
37
+ 'latex' => 'tex'
38
+ }
39
+
40
+ # A Configuration object models a pandocomatic configuration.
41
+ class Configuration
42
+
43
+ # Create a new Configuration instance based on the command-line
44
+ # options, a data_dir, and a configuration file.
45
+ def initialize options, data_dir, configuration_file
46
+ @data_dir = data_dir
23
47
 
24
- DEFAULT_CONFIG = YAML.load_file File.join(__dir__, 'default_configuration.yaml')
48
+ load configuration_file
49
+ end
25
50
 
26
- FORMAT_TO_EXT = {
27
- 'native' => 'hs',
28
- 'markdown' => 'md',
29
- 'markdown_strict' => 'md',
30
- 'markdown_phpextra' => 'md',
31
- 'markdown_github' => 'md',
32
- 'html5' => 'html',
33
- 'docx' => 'docx',
34
- 'latex' => 'tex'
35
- }
51
+ # Read a configuration file and create a pandocomatic configuration object
52
+ #
53
+ # @param [String] filename Path to the configuration yaml file
54
+ # @return [Configuration] a pandocomatic configuration object
55
+ def load(filename)
56
+ begin
57
+ path = File.absolute_path filename
58
+ settings = YAML.load_file path
59
+ if settings['settings'] and settings['settings']['data-dir'] then
60
+ data_dir = settings['settings']['data-dir']
61
+ src_dir = File.dirname filename
62
+ if data_dir.start_with? '.' then
63
+ @data_dir = File.absolute_path data_dir, src_dir
64
+ else
65
+ @data_dir = data_dir
66
+ end
67
+ end
68
+ rescue StandardError => e
69
+ raise ConfigurationError.new(:unable_to_load_config_file, e, filename)
70
+ end
36
71
 
37
- # Configuration describes a pandocomatic configuration.
38
- class Configuration
72
+ # hidden files will always be skipped, as will pandocomatic
73
+ # configuration files, unless explicitly set to not skip via the
74
+ # "unskip" option
39
75
 
40
- def initialize options, data_dir, configuration_file
41
- @data_dir = data_dir
76
+ @settings = {'skip' => ['.*', 'pandocomatic.yaml']}
42
77
 
43
- load configuration_file
44
- end
78
+ @templates = {}
79
+ @convert_patterns = {}
45
80
 
46
- # Read a configuration file and create a pandocomatic configuration object
47
- #
48
- # @param [String] filename Path to the configuration yaml file
49
- # @return [Configuration] a pandocomatic configuration object
50
- def load(filename)
51
- begin
52
- path = File.absolute_path filename
53
- settings = YAML.load_file path
54
- if settings['settings'] and settings['settings']['data-dir'] then
55
- data_dir = settings['settings']['data-dir']
56
- src_dir = File.dirname filename
57
- if data_dir.start_with? '.' then
58
- @data_dir = File.absolute_path data_dir, src_dir
59
- else
60
- @data_dir = data_dir
61
- end
81
+ configure settings
62
82
  end
63
- rescue StandardError => e
64
- raise ConfigurationError.new(:unable_to_load_config_file, e, filename)
65
- end
66
83
 
67
- # hidden files will always be skipped, as will pandocomatic
68
- # configuration files, unless explicitly set to not skip via the
69
- # "unskip" option
84
+ # Update this configuration with a configuration file
85
+ #
86
+ # @param [String] filename path to the configuration file
87
+ #
88
+ # @return [Configuration] a new configuration
89
+ def reconfigure(filename)
90
+ begin
91
+ settings = YAML.load_file filename
92
+ new_config = Marshal.load(Marshal.dump(self))
93
+ new_config.configure settings
94
+ new_config
95
+ rescue StandardError => e
96
+ raise ConfigurationError.new(:unable_to_load_config_file, e, filename)
97
+ end
98
+ end
70
99
 
71
- @settings = {'skip' => ['.*', 'pandocomatic.yaml']}
100
+ # Configure pandocomatic based on a settings Hash
101
+ #
102
+ # @param settings [Hash] a settings Hash to mixin in this
103
+ # Configuration.
104
+ def configure(settings)
105
+ reset_settings settings['settings'] if settings.has_key? 'settings'
106
+ if settings.has_key? 'templates' then
107
+ settings['templates'].each do |name, template|
108
+ full_template = {
109
+ 'extends' => [],
110
+ 'glob' => [],
111
+ 'setup' => [],
112
+ 'preprocessors' => [],
113
+ 'metadata' => {},
114
+ 'pandoc' => {},
115
+ 'postprocessors' => [],
116
+ 'cleanup' => []
117
+ }
118
+
119
+ reset_template name, full_template.merge(template)
120
+ end
121
+ end
122
+ end
72
123
 
73
- @templates = {}
74
- @convert_patterns = {}
124
+ # Convert this Configuration to a String
125
+ #
126
+ # @return [String]
127
+ def to_s()
128
+ marshal_dump
129
+ end
75
130
 
76
- configure settings
77
- end
131
+ # Should the source file be skipped given this Configuration?
132
+ #
133
+ # @param src [String] path to a source file
134
+ # @return [Boolean] True if this source file matches the pattern in
135
+ # the 'skip' setting, false otherwise.
136
+ def skip?(src)
137
+ if @settings.has_key? 'skip' then
138
+ @settings['skip'].any? {|glob| File.fnmatch glob, File.basename(src)}
139
+ else
140
+ false
141
+ end
142
+ end
78
143
 
79
- # Update this configuration with a configuration file
80
- #
81
- # @param [String] filename path to the configuration file
82
- #
83
- # @return [Configuration] a new configuration
84
- def reconfigure(filename)
85
- begin
86
- settings = YAML.load_file filename
87
- new_config = Marshal.load(Marshal.dump(self))
88
- new_config.configure settings
89
- new_config
90
- rescue StandardError => e
91
- raise ConfigurationError.new(:unable_to_load_config_file, e, filename)
92
- end
93
- end
144
+ # Should the source file be converted given this Configuration?
145
+ #
146
+ # @param src [String] True if this source file matches the 'glob'
147
+ # patterns in a template, false otherwise.
148
+ def convert?(src)
149
+ @convert_patterns.values.flatten.any? {|glob| File.fnmatch glob, File.basename(src)}
150
+ end
94
151
 
95
- def configure(settings)
96
- reset_settings settings['settings'] if settings.has_key? 'settings'
97
- if settings.has_key? 'templates' then
98
- settings['templates'].each do |name, template|
99
- full_template = {
100
- 'glob' => [],
101
- 'setup' => [],
102
- 'preprocessors' => [],
103
- 'metadata' => {},
104
- 'pandoc' => {},
105
- 'postprocessors' => [],
106
- 'cleanup' => []
107
- }
108
-
109
- reset_template name, full_template.merge(template)
152
+ # Should pandocomatic be run recursively given this Configuration?
153
+ #
154
+ # @return [Boolean] True if the setting 'recursive' is true, false
155
+ # otherwise
156
+ def recursive?()
157
+ @settings['recursive']
110
158
  end
111
- end
112
- end
113
159
 
114
- def marshal_dump()
115
- [@data_dir, @settings, @templates, @convert_patterns]
116
- end
160
+ # Should pandocomatic follow symbolic links given this Configuration?
161
+ #
162
+ # @return [Boolean] True if the setting 'follow_links' is true, false
163
+ # otherwise
164
+ def follow_links?()
165
+ @settings['follow_links']
166
+ end
117
167
 
118
- def marshal_load(array)
119
- @data_dir, @settings, @templates, @convert_patterns = array
120
- end
168
+ # Set the extension of the destination file given this Confguration,
169
+ # template, and metadata
170
+ #
171
+ # @param dst [String] path to a destination file
172
+ # @param template_name [String] the name of the template used to
173
+ # convert to destination
174
+ # @param metadata [PandocMetadata] the metadata in the source file
175
+ def set_extension(dst, template_name, metadata)
176
+ dir = File.dirname dst
177
+ ext = File.extname dst
178
+ basename = File.basename dst, ext
179
+ File.join dir, "#{basename}.#{find_extension(dst, template_name, metadata)}"
180
+ end
121
181
 
122
- def to_s()
123
- marshal_dump
124
- end
182
+ # Find the extension of the destination file given this Confguration,
183
+ # template, and metadata
184
+ #
185
+ # @param dst [String] path to a destination file
186
+ # @param template_name [String] the name of the template used to
187
+ # convert to destination
188
+ # @param metadata [PandocMetadata] the metadata in the source file
189
+ #
190
+ # @return [String] the extension to use for the destination file
191
+ def find_extension(dst, template_name, metadata)
192
+ extension = "html"
193
+ if template_name.nil? or template_name.empty? then
194
+ if metadata.has_pandocomatic?
195
+ pandocomatic = metadata.pandocomatic
196
+ if pandocomatic.has_key? "pandoc"
197
+ pandoc = pandocomatic["pandoc"]
198
+
199
+ if pandoc.has_key? "to"
200
+ extension = pandoc["to"]
201
+ end
202
+ end
203
+ end
204
+ else
205
+ # TODO: what if there is no pandoc.to?
206
+ if @templates[template_name].has_key? "pandoc"
207
+ pandoc = @templates[template_name]["pandoc"]
208
+ if pandoc.has_key? "to"
209
+ extension = pandoc["to"]
210
+ end
211
+ end
212
+ end
125
213
 
126
- def skip?(src)
127
- if @settings.has_key? 'skip' then
128
- @settings['skip'].any? {|glob| File.fnmatch glob, File.basename(src)}
129
- else
130
- false
131
- end
132
- end
214
+ extension = FORMAT_TO_EXT[extension] || extension
215
+ return extension
216
+ end
133
217
 
134
- def convert?(src)
135
- @convert_patterns.values.flatten.any? {|glob| File.fnmatch glob, File.basename(src)}
136
- end
218
+ # Is there a template with template_name in this Configuration?
219
+ #
220
+ # @param template_name [String] a template's name
221
+ #
222
+ # @return [Boolean] True if there is a template with name equal to
223
+ # template_name in this Configuration
224
+ def has_template?(template_name)
225
+ @templates.has_key? template_name
226
+ end
137
227
 
138
- def recursive?()
139
- @settings['recursive']
140
- end
228
+ # Get the template with template_name from this Configuration
229
+ #
230
+ # @param template_name [String] a template's name
231
+ #
232
+ # @return [Hash] The template with template_name.
233
+ def get_template(template_name)
234
+ @templates[template_name]
235
+ end
141
236
 
142
- def follow_links?()
143
- @settings['follow_links']
144
- end
237
+ # Determine the template to use with this source document given this
238
+ # Configuration.
239
+ #
240
+ # @param src [String] path to the source document
241
+ # @return [String] the template's name to use
242
+ def determine_template(src)
243
+ @convert_patterns.select do |template_name, globs|
244
+ globs.any? {|glob| File.fnmatch glob, File.basename(src)}
245
+ end.keys.first
246
+ end
145
247
 
146
- def set_extension(dst, template_name, metadata)
147
- dir = File.dirname dst
148
- ext = File.extname dst
149
- basename = File.basename dst, ext
150
- File.join dir, "#{basename}.#{find_extension(dst, template_name, metadata)}"
151
- end
248
+ # Update the path to an executable processor or executor given this
249
+ # Configuration
250
+ #
251
+ # @param path [String] path to the executable
252
+ # @param src_dir [String] the source directory from which pandocomatic
253
+ # conversion process has been started
254
+ # @param check_executable [Booelan = false] Should the executable be
255
+ # verified to be executable? Defaults to false.
256
+ #
257
+ # @return [String] the updated path.
258
+ def update_path(path, src_dir, check_executable = false)
259
+ updated_path = path
260
+ if path.start_with? './'
261
+ # refers to a local (to file) dir
262
+ updated_path = File.join src_dir, path
263
+ else
264
+ if path.start_with? '/'
265
+ updated_path = path
266
+ else
267
+ if check_executable
268
+ updated_path = Configuration.which path
269
+ end
270
+
271
+ if updated_path.nil? or not updated_path.start_with? '/' then
272
+ # refers to data-dir
273
+ updated_path = File.join @data_dir, path
274
+ end
275
+ end
276
+ end
152
277
 
153
- def find_extension(dst, template_name, metadata)
154
- extension = "html"
155
- if template_name.nil? or template_name.empty? then
156
- if metadata.has_pandocomatic?
157
- pandocomatic = metadata.pandocomatic
158
- if pandocomatic.has_key? "pandoc"
159
- pandoc = pandocomatic["pandoc"]
278
+ updated_path
279
+ end
160
280
 
161
- if pandoc.has_key? "to"
162
- extension = pandoc["to"]
281
+ private
282
+
283
+ # Reset the settings for pandocomatic based on a new settings Hash
284
+ #
285
+ # @settings [Hash] the new settings to use to reset the settings in
286
+ # this Configuration with.
287
+ def reset_settings(settings)
288
+ settings.each do |setting, value|
289
+ case setting
290
+ when 'skip'
291
+ @settings['skip'] = @settings['skip'].concat(value).uniq
292
+ when 'data-dir'
293
+ next # skip data-dir setting; is set once in initialization
294
+ else
295
+ @settings[setting] = value
163
296
  end
164
297
  end
165
- end
166
- else
167
- # TODO: what if there is no pandoc.to?
168
- if @templates[template_name].has_key? "pandoc"
169
- pandoc = @templates[template_name]["pandoc"]
170
- if pandoc.has_key? "to"
171
- extension = pandoc["to"]
172
- end
173
298
  end
174
- end
175
-
176
- extension = FORMAT_TO_EXT[extension] || extension
177
- return extension
178
- end
179
-
180
- def has_template?(template_name)
181
- @templates.has_key? template_name
182
- end
183
299
 
184
- def get_template(template_name)
185
- @templates[template_name]
186
- end
300
+ # Merge two templates
301
+ #
302
+ # @param base_template [Hash] the base template
303
+ # @param mixin_template [Hash] the template to mixin into the base template
304
+ # @return [Hash] the merged templates
305
+ def merge(base_template, mixin_template)
306
+ fields = [
307
+ 'extends',
308
+ 'glob',
309
+ 'metadata',
310
+ 'setup',
311
+ 'preprocessors',
312
+ 'pandoc',
313
+ 'postprocessors',
314
+ 'cleanup'
315
+ ]
316
+
317
+ fields.each do |field|
318
+ case field
319
+ when 'extends'
320
+ if mixin_template[field] and mixin_template[field].is_a? String
321
+ mixin_template[field] = [mixin_template[field]]
322
+ end
323
+ when
324
+ 'cleanup',
325
+ 'setup',
326
+ 'preprocessors',
327
+ 'postprocessors',
328
+ 'glob'
329
+
330
+ if base_template[field] then
331
+ # If both templates have this field, concat the arrays
332
+ # and remove duplicates
333
+ if mixin_template[field] then
334
+ base_template[field].concat(mixin_template[field]).uniq!
335
+ end
336
+ else
337
+ # If the base does not have this fiel yet, assign it
338
+ # the mixin's
339
+ if mixin_template[field] then
340
+ base_template[field] = mixin_template[field]
341
+ end
342
+ end
343
+ when 'pandoc', 'metadata'
344
+ # Merge Hashes
345
+ if base_template[field] then
346
+ if mixin_template[field] then
347
+ base_template[field].merge! mixin_template[field]
348
+ end
349
+ else
350
+ if mixin_template[field] then
351
+ base_template[field] = mixin_template[field]
352
+ end
353
+ end
354
+ end
355
+ end
187
356
 
188
- def determine_template(src)
189
- @convert_patterns.select do |template_name, globs|
190
- globs.any? {|glob| File.fnmatch glob, File.basename(src)}
191
- end.keys.first
192
- end
357
+ base_template
358
+ end
193
359
 
194
- def update_path(path, src_dir, check_executable = false)
195
- updated_path = path
196
- if path.start_with? './'
197
- # refers to a local (to file) dir
198
- updated_path = File.join src_dir, path
199
- else
200
- if path.start_with? '/'
201
- updated_path = path
202
- else
203
- if check_executable
204
- updated_path = Configuration.which path
360
+ # Resolve the templates the templates extends and mixes them in, in
361
+ # order of occurrence.
362
+ #
363
+ # @param template [Hash] the template to extend
364
+ # @return [Hash] the resolved template
365
+ def extend_template(template)
366
+ resolved_template = {};
367
+ if template.has_key? 'extends' and not template['extends'].empty?
368
+ to_extend = template['extends']
369
+ to_extend = [to_extend] if to_extend.is_a? String
370
+
371
+ to_extend.each do |name|
372
+ if @templates.has_key? name
373
+ resolved_template = merge resolved_template, @templates[name]
374
+ else
375
+ warn "Cannot find template with name '#{parent_template_name}'. Skipping this template while extending: '#{template.to_s}'."
376
+ end
205
377
  end
206
378
 
207
- if updated_path.nil? or not updated_path.start_with? '/' then
208
- # refers to data-dir
209
- updated_path = File.join @data_dir, path
210
- end
379
+ resolved_template
211
380
  end
212
- end
213
381
 
214
- updated_path
215
- end
216
-
217
- private
218
-
219
- def reset_settings(settings)
220
- settings.each do |setting, value|
221
- case setting
222
- when 'skip'
223
- @settings['skip'] = @settings['skip'].concat(value).uniq
224
- when 'data-dir'
225
- next # skip data-dir setting; is set once in initialization
226
- else
227
- @settings[setting] = value
382
+ merge resolved_template, template
228
383
  end
229
- end
230
- end
231
384
 
232
- def reset_template(name, template)
233
- if @templates.has_key? name then
234
- fields = ['glob', 'cleanup', 'setup', 'preprocessors', 'pandoc', 'postprocessors']
235
- fields.each do |field|
236
- case field
237
- when 'cleanup', 'setup', 'preprocessors', 'postprocessors', 'glob'
238
- if @templates[name][field] then
239
- if template[field] then
240
- @templates[name][field].concat(template[field]).uniq!
241
- end
385
+ # Reset the template with name in this Configuration based on a new
386
+ # template
387
+ #
388
+ # @param name [String] the name of the template in this Configuration
389
+ # @param template [Hash] the template to use to update the template in
390
+ # this Configuarion with
391
+ def reset_template(name, template)
392
+ extended_template = extend_template template
393
+
394
+ if @templates.has_key? name then
395
+ @templates[name] = merge @templates[name], extended_template
242
396
  else
243
- if template[field] then
244
- @templates[name][field] = template[field]
245
- end
397
+ @templates[name] = extended_template
246
398
  end
247
- when 'pandoc', 'metadata'
248
- if @templates[name][field] then
249
- if template[field] then
250
- @templates[name][field].merge! template[field]
251
- end
252
- else
253
- if template[field] then
254
- @templates[name][field] = template[field]
255
- end
399
+
400
+ if extended_template.has_key? 'glob' then
401
+ @convert_patterns[name] = extended_template['glob']
256
402
  end
257
- end
258
403
  end
259
- else
260
- @templates[name] = template
261
- end
262
-
263
- if template.has_key? 'glob' then
264
- @convert_patterns[name] = template['glob']
265
- end
266
- end
267
404
 
268
- # Cross-platform way of finding an executable in the $PATH.
269
- #
270
- # which('ruby') #=> /usr/bin/ruby
271
- #
272
- # Taken from:
273
- # http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby#5471032
274
- def self.which(cmd)
275
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
276
- ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
277
- exts.each { |ext|
278
- exe = File.join(path, "#{cmd}#{ext}")
279
- return exe if File.executable?(exe) &&
280
- !File.directory?(exe)
281
- }
405
+ # Cross-platform way of finding an executable in the $PATH.
406
+ #
407
+ # which('ruby') #=> /usr/bin/ruby
408
+ #
409
+ # Taken from:
410
+ # http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby#5471032
411
+ def self.which(cmd)
412
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
413
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
414
+ exts.each { |ext|
415
+ exe = File.join(path, "#{cmd}#{ext}")
416
+ return exe if File.executable?(exe) &&
417
+ !File.directory?(exe)
418
+ }
419
+ end
420
+ return nil
421
+ end
422
+
423
+ def marshal_dump()
424
+ [@data_dir, @settings, @templates, @convert_patterns]
282
425
  end
283
- return nil
284
- end
285
426
 
286
- end
427
+ def marshal_load(array)
428
+ @data_dir, @settings, @templates, @convert_patterns = array
429
+ end
287
430
 
431
+ end
288
432
  end
@@ -18,93 +18,149 @@
18
18
  #++
19
19
  module Pandocomatic
20
20
 
21
- require 'json'
22
- require 'yaml'
23
- require 'paru'
24
- require 'paru/pandoc2yaml'
25
-
26
- require_relative './error/pandoc_error.rb'
27
- require_relative './error/io_error.rb'
28
-
29
- class PandocMetadata < Hash
30
-
31
- def self.extract_metadata input_document
32
- begin
33
- Paru::Pandoc2Yaml.extract_metadata(input_document)
34
- rescue StandardError => e
35
- raise IOError.new(:error_opening_file, e, input_document)
36
- end
37
- end
21
+ require 'json'
22
+ require 'yaml'
23
+ require 'paru'
24
+
25
+ require_relative './error/pandoc_error.rb'
26
+ require_relative './error/io_error.rb'
27
+
28
+ # PandocMetadata represents the metadata with pandoc options set in
29
+ # templates and input files.
30
+ class PandocMetadata < Hash
31
+
32
+ # Extract the metadata from an input file
33
+ #
34
+ # @param input_document [String] a path to an input file
35
+ # @return [String] the input document's metadata in the YAML format.
36
+ def self.extract_metadata input_document
37
+ begin
38
+ pandoc2yaml File.read(input_document)
39
+ rescue StandardError => e
40
+ raise IOError.new(:error_opening_file, e, input_document)
41
+ end
42
+ end
38
43
 
39
- # Collect the metadata embedded in the src file
40
- def self.load_file src
41
- yaml_metadata = extract_metadata src
44
+ # Extract the YAML metadata from an input string
45
+ #
46
+ # @param input [String] the input string
47
+ # @return [String] the YAML data embedded in the input string
48
+ def self.pandoc2yaml(input)
49
+ input
50
+ .scan(/^---[ \t]*\n(.+?)^(?:---|\.\.\.)[ \t]*\n/m)
51
+ .flatten
52
+ .map{|yaml| yaml.strip}
53
+ .join("\n")
54
+ end
42
55
 
43
- if yaml_metadata.empty? then
44
- return PandocMetadata.new
45
- else
46
- return PandocMetadata.new YAML.load(yaml_metadata)
47
- end
48
- end
49
-
50
- def initialize hash = {}
51
- super
52
- merge! hash
53
- end
56
+ # Collect the metadata embedded in the src file and create a new
57
+ # PandocMetadata instance
58
+ #
59
+ # @param src [String] the path to the file to load metadata from
60
+ # @return [PandocMetadata] the metadata in the source file, or an empty
61
+ # one if no such metadata is contained in the source file.
62
+ def self.load_file src
63
+ yaml_metadata = extract_metadata src
64
+
65
+ if yaml_metadata.empty? then
66
+ return PandocMetadata.new
67
+ else
68
+ return PandocMetadata.new YAML.load(yaml_metadata)
69
+ end
70
+ end
54
71
 
55
- def has_template?()
56
- has_pandocomatic? and pandocomatic.has_key? 'use-template' and not pandocomatic['use-template'].empty?
57
- end
72
+ # Creat e new PandocMetadata object based on the properties contained
73
+ # in a Hash
74
+ #
75
+ # @param hash [Hash] initial properties for this new PandocMetadata
76
+ # object
77
+ # @return [PandocMetadata]
78
+ def initialize hash = {}
79
+ super
80
+ merge! hash
81
+ end
58
82
 
59
- def templates()
60
- if has_template?
61
- if pandocomatic['use-template'].is_a? Array
62
- pandocomatic['use-template']
83
+ # Does this PandocMetadata object use a template?
84
+ #
85
+ # @return [Boolean] true if it has a key 'use-template' among the
86
+ # pandocomatic template properties.
87
+ def has_template?()
88
+ has_pandocomatic? and pandocomatic.has_key? 'use-template' and not pandocomatic['use-template'].empty?
89
+ end
90
+
91
+ # Get all the templates of this PandocMetadata oject
92
+ #
93
+ # @return [Array] an array of templates used in this PandocMetadata
94
+ # object
95
+ def templates()
96
+ if has_template?
97
+ if pandocomatic['use-template'].is_a? Array
98
+ pandocomatic['use-template']
99
+ else
100
+ [pandocomatic['use-template']]
101
+ end
63
102
  else
64
- [pandocomatic['use-template']]
103
+ [""]
65
104
  end
66
- else
67
- [""]
68
105
  end
69
- end
70
-
71
- def template_name()
72
- if has_template? then
73
- pandocomatic['use-template']
74
- else
75
- ''
76
- end
77
- end
78
106
 
79
- # TODO: allow a pandoc block outside a pandocomatic block to make
80
- # pandocomatic work like paru's do-pandoc.rb.
107
+ # Get the used template's name
108
+ #
109
+ # @return [String] the name of the template used, if any, "" otherwise.
110
+ def template_name()
111
+ if has_template? then
112
+ pandocomatic['use-template']
113
+ else
114
+ ''
115
+ end
116
+ end
117
+
118
+ # Does this PandocMetadata object have a pandocomatic property?
119
+ #
120
+ # @return [Boolean] True if this PandocMetadata object has a Hash
121
+ # property named "pandocomatic_". False otherwise.
122
+ #
123
+ # Note. For backward compatibility with older versions of
124
+ # pandocomatic, properties named "pandocomatic" (without the trailing
125
+ # underscore) are also accepted.
126
+ def has_pandocomatic?()
127
+ config = nil
128
+ if has_key? 'pandocomatic' or has_key? 'pandocomatic_'
129
+ config = self['pandocomatic'] if has_key? 'pandocomatic'
130
+ config = self['pandocomatic_'] if has_key? 'pandocomatic_'
131
+ end
132
+ config.is_a? Hash
133
+ end
81
134
 
82
- def has_pandoc_options?()
83
- has_pandocomatic? and pandocomatic.has_key? 'pandoc'
84
- end
135
+ # Get the pandoc options for this PandocMetadata object
136
+ #
137
+ # @return [Hash] the pandoc options if there are any, an empty Hash
138
+ # otherwise.
139
+ def pandoc_options()
140
+ if has_pandoc_options? then
141
+ pandocomatic['pandoc']
142
+ else
143
+ {}
144
+ end
145
+ end
85
146
 
86
- def pandoc_options()
87
- if has_pandoc_options? then
88
- pandocomatic['pandoc']
89
- else
90
- {}
91
- end
92
- end
147
+ # Get the pandocomatic property of this PandocMetadata object
148
+ #
149
+ # @return [Hash] the pandocomatic property as a Hash, if any, an empty
150
+ # Hash otherwise.
151
+ def pandocomatic()
152
+ return self['pandocomatic'] if has_key? 'pandocomatic'
153
+ return self['pandocomatic_'] if has_key? 'pandocomatic_'
154
+ end
93
155
 
94
- def has_pandocomatic?()
95
- config = nil
96
- if has_key? 'pandocomatic' or has_key? 'pandocomatic_'
97
- config = self['pandocomatic'] if has_key? 'pandocomatic'
98
- config = self['pandocomatic_'] if has_key? 'pandocomatic_'
99
- end
100
- config.is_a? Hash
101
- end
156
+ # Does this PandocMetadata object has a pandoc options property?
157
+ #
158
+ # @return [Boolean] True if there is a pandoc options property in this
159
+ # PandocMetadata object. False otherwise.
160
+ def has_pandoc_options?()
161
+ has_pandocomatic? and pandocomatic.has_key? 'pandoc'
162
+ end
102
163
 
103
- def pandocomatic()
104
- return self['pandocomatic'] if has_key? 'pandocomatic'
105
- return self['pandocomatic_'] if has_key? 'pandocomatic_'
106
164
  end
107
165
 
108
- end
109
-
110
166
  end
@@ -44,7 +44,7 @@ module Pandocomatic
44
44
  require_relative './command/convert_file_multiple_command.rb'
45
45
 
46
46
  class Pandocomatic
47
- VERSION = [0, 1, 4, 9]
47
+ VERSION = [0, 1, 4, 10]
48
48
  CONFIG_FILE = 'pandocomatic.yaml'
49
49
 
50
50
  def self.run(args)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pandocomatic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4.9
4
+ version: 0.1.4.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Huub de Beer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-12 00:00:00.000000000 Z
11
+ date: 2017-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: paru