pandocomatic 0.2.8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pandocomatic/cli.rb +81 -64
  3. data/lib/pandocomatic/command/command.rb +37 -35
  4. data/lib/pandocomatic/command/convert_dir_command.rb +44 -46
  5. data/lib/pandocomatic/command/convert_file_command.rb +314 -290
  6. data/lib/pandocomatic/command/convert_file_multiple_command.rb +56 -53
  7. data/lib/pandocomatic/command/convert_list_command.rb +31 -34
  8. data/lib/pandocomatic/command/copy_file_command.rb +14 -15
  9. data/lib/pandocomatic/command/create_link_command.rb +24 -27
  10. data/lib/pandocomatic/command/skip_command.rb +12 -15
  11. data/lib/pandocomatic/configuration.rb +682 -867
  12. data/lib/pandocomatic/default_configuration.yaml +4 -0
  13. data/lib/pandocomatic/error/cli_error.rb +30 -26
  14. data/lib/pandocomatic/error/configuration_error.rb +10 -9
  15. data/lib/pandocomatic/error/io_error.rb +13 -13
  16. data/lib/pandocomatic/error/pandoc_error.rb +10 -9
  17. data/lib/pandocomatic/error/pandocomatic_error.rb +15 -14
  18. data/lib/pandocomatic/error/processor_error.rb +9 -9
  19. data/lib/pandocomatic/error/template_error.rb +50 -0
  20. data/lib/pandocomatic/input.rb +53 -54
  21. data/lib/pandocomatic/multiple_files_input.rb +79 -72
  22. data/lib/pandocomatic/output.rb +29 -0
  23. data/lib/pandocomatic/pandoc_metadata.rb +193 -181
  24. data/lib/pandocomatic/pandocomatic.rb +101 -97
  25. data/lib/pandocomatic/pandocomatic_yaml.rb +69 -0
  26. data/lib/pandocomatic/path.rb +171 -0
  27. data/lib/pandocomatic/printer/command_printer.rb +7 -5
  28. data/lib/pandocomatic/printer/configuration_errors_printer.rb +7 -6
  29. data/lib/pandocomatic/printer/error_printer.rb +12 -7
  30. data/lib/pandocomatic/printer/finish_printer.rb +11 -10
  31. data/lib/pandocomatic/printer/help_printer.rb +8 -6
  32. data/lib/pandocomatic/printer/printer.rb +34 -34
  33. data/lib/pandocomatic/printer/summary_printer.rb +39 -33
  34. data/lib/pandocomatic/printer/version_printer.rb +8 -8
  35. data/lib/pandocomatic/printer/views/cli_error.txt +5 -0
  36. data/lib/pandocomatic/printer/views/configuration_error.txt +2 -1
  37. data/lib/pandocomatic/printer/views/error.txt +1 -1
  38. data/lib/pandocomatic/printer/views/finish.txt +1 -1
  39. data/lib/pandocomatic/printer/views/help.txt +27 -15
  40. data/lib/pandocomatic/printer/views/summary.txt +7 -1
  41. data/lib/pandocomatic/printer/views/template_error.txt +1 -0
  42. data/lib/pandocomatic/printer/views/version.txt +3 -3
  43. data/lib/pandocomatic/printer/views/warning.txt +1 -1
  44. data/lib/pandocomatic/printer/warning_printer.rb +21 -19
  45. data/lib/pandocomatic/processor.rb +28 -28
  46. data/lib/pandocomatic/processors/fileinfo_preprocessor.rb +35 -30
  47. data/lib/pandocomatic/processors/metadata_preprocessor.rb +23 -22
  48. data/lib/pandocomatic/template.rb +244 -0
  49. data/lib/pandocomatic/warning.rb +24 -25
  50. metadata +32 -12
@@ -1,103 +1,110 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #--
2
4
  # Copyright 2019 Huub de Beer <Huub@heerdebeer.org>
3
- #
5
+ #
4
6
  # This file is part of pandocomatic.
5
- #
7
+ #
6
8
  # Pandocomatic is free software: you can redistribute it and/or modify
7
9
  # it under the terms of the GNU General Public License as published by the
8
10
  # Free Software Foundation, either version 3 of the License, or (at your
9
11
  # option) any later version.
10
- #
12
+ #
11
13
  # Pandocomatic is distributed in the hope that it will be useful, but
12
14
  # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
15
  # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
16
  # for more details.
15
- #
17
+ #
16
18
  # You should have received a copy of the GNU General Public License along
17
19
  # with pandocomatic. If not, see <http://www.gnu.org/licenses/>.
18
20
  #++
19
21
  module Pandocomatic
22
+ require 'tempfile'
23
+ require_relative './input'
20
24
 
21
- require 'tempfile'
22
- require_relative './input.rb'
25
+ # A specific Input class to handle multiple input files
26
+ class MultipleFilesInput < Input
27
+ # Create a new MultipleFilesInput. As a side-effect a temporary file
28
+ # is created as well containing the content of all the files in input.
29
+ #
30
+ # @param input [String[]] a list with input files
31
+ def initialize(input, config)
32
+ super(input)
33
+ @config = config
34
+ create_temp_file
35
+ end
23
36
 
24
- # A specific Input class to handle multiple input files
25
- class MultipleFilesInput < Input
37
+ # The name of this input
38
+ #
39
+ # @return String
40
+ def name
41
+ @tmp_file.path
42
+ end
26
43
 
27
- # Create a new MultipleFilesInput. As a side-effect a temporary file
28
- # is created as well containing the content of all the files in input.
29
- #
30
- # @param input [String[]] a list with input files
31
- def initialize(input, config)
32
- super(input)
33
- @config = config
34
- create_temp_file
35
- end
44
+ # Is this input a directory? A MultipleFilesInput cannot be a
45
+ # directory
46
+ #
47
+ # @return Boolean
48
+ def directory?
49
+ false
50
+ end
36
51
 
37
- # The name of this input
38
- #
39
- # @return String
40
- def name()
41
- @tmp_file.path
42
- end
52
+ # Destroy the temporary file created for this MultipleFilesInput
53
+ def destroy!
54
+ return if @tmp_file.nil?
43
55
 
44
- # Is this input a directory? A MultipleFilesInput cannot be a
45
- # directory
46
- #
47
- # @return Boolean
48
- def directory?()
49
- false
50
- end
56
+ @tmp_file.close
57
+ @tmp_file.unlink
58
+ end
51
59
 
52
- # Destroy the temporary file created for this MultipleFilesInput
53
- def destroy!()
54
- if not @tmp_file.nil?
55
- @tmp_file.close
56
- @tmp_file.unlink
57
- end
60
+ # A string representation of this Input
61
+ #
62
+ # @return String
63
+ def to_s
64
+ input_string = @input_files.first
65
+ previous_dir = File.dirname @input_files.first
66
+ @input_files.slice(1..-1).each do |f|
67
+ current_dir = File.dirname f
68
+ if current_dir == previous_dir
69
+ input_string += " + #{File.basename f}"
70
+ else
71
+ previous_dir = current_dir
72
+ input_string += " + #{f}"
58
73
  end
74
+ end
59
75
 
60
- # A string representation of this Input
61
- #
62
- # @return String
63
- def to_s()
64
- input_string = @input_files.first
65
- previous_dir = File.dirname @input_files.first
66
- @input_files.slice(1..-1).each do |f|
67
- current_dir = File.dirname f
68
- if current_dir == previous_dir
69
- input_string += " + #{File.basename f}"
70
- else
71
- previous_dir = current_dir
72
- input_string += " + #{f}"
73
- end
74
- end
75
-
76
- input_string
77
- end
76
+ input_string
77
+ end
78
78
 
79
- private
79
+ private
80
80
 
81
- def create_temp_file()
82
- # Concatenate all input files into one (temporary) input file
83
- # created in the same directory as the first input file
84
- @tmp_file = Tempfile.new("pandocomatic_tmp_", File.dirname(self.absolute_path))
81
+ # rubocop:disable Metrics/AbcSize
85
82
 
86
- contents = @input_files.map{|file|
87
- @errors.push IOError.new(:file_does_not_exist, nil, file) unless File.exist? file
88
- @errors.push IOError.new(:file_is_not_a_file, nil, file) unless File.file? file
89
- @errors.push IOError.new(:file_is_not_readable, nil, file) unless File.readable? file
90
- File.read File.absolute_path(file)
91
- }.join("\n\n")
83
+ def create_temp_file
84
+ # Concatenate all input files into one (temporary) input file
85
+ # created in the same directory as the first input file
86
+ @tmp_file = Tempfile.new('pandocomatic_tmp_', File.dirname(absolute_path))
92
87
 
93
- metadata = PandocMetadata.load contents
88
+ contents = @input_files.map do |file|
89
+ @errors.push IOError.new(:file_does_not_exist, nil, file) unless File.exist? file
90
+ @errors.push IOError.new(:file_is_not_a_file, nil, file) unless File.file? file
91
+ @errors.push IOError.new(:file_is_not_readable, nil, file) unless File.readable? file
92
+ File.read File.absolute_path(file)
93
+ end.join("\n\n")
94
94
 
95
- if not metadata.unique?
96
- warn "\nWarning: Encountered the pandocomatic metadata property in more than one YAML metadata block. Only the pandocomatic property from the first YAML metadata block is being used; the other pandocomatic properties have been discarded.\n\n"
97
- end
95
+ metadata = PandocMetadata.load contents
98
96
 
99
- @tmp_file.write contents
100
- @tmp_file.rewind
101
- end
97
+ unless metadata.unique?
98
+ warn "\nWarning: Encountered the pandocomatic metadata property in"\
99
+ ' more than one YAML metadata block. Only the pandocomatic property'\
100
+ ' from the first YAML metadata block is being used; the other'\
101
+ " pandocomatic properties have been discarded.\n\n"
102
+ end
103
+
104
+ @tmp_file.write contents
105
+ @tmp_file.rewind
102
106
  end
107
+
108
+ # rubocop:enable Metrics/AbcSize
109
+ end
103
110
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ #--
4
+ # Copyright 2021 Huub de Beer <Huub@heerdebeer.org>
5
+ #
6
+ # This file is part of pandocomatic.
7
+ #
8
+ # Pandocomatic is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by the
10
+ # Free Software Foundation, either version 3 of the License, or (at your
11
+ # option) any later version.
12
+ #
13
+ # Pandocomatic is distributed in the hope that it will be useful, but
14
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16
+ # for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License along
19
+ # with pandocomatic. If not, see <http://www.gnu.org/licenses/>.
20
+ #++
21
+ module Pandocomatic
22
+ require_relative './configuration'
23
+
24
+ # Generic class to handle output in a general manner.
25
+ class Output
26
+ # Create a new Output
27
+ def initialize; end
28
+ end
29
+ end
@@ -1,214 +1,226 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #--
2
- # Copyright 2014, 2015, 2016, 2017, Huub de Beer <Huub@heerdebeer.org>
3
- #
4
+ # Copyright 2014-2022, Huub de Beer <Huub@heerdebeer.org>
5
+ #
4
6
  # This file is part of pandocomatic.
5
- #
7
+ #
6
8
  # Pandocomatic is free software: you can redistribute it and/or modify
7
9
  # it under the terms of the GNU General Public License as published by the
8
10
  # Free Software Foundation, either version 3 of the License, or (at your
9
11
  # option) any later version.
10
- #
12
+ #
11
13
  # Pandocomatic is distributed in the hope that it will be useful, but
12
14
  # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
15
  # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
16
  # for more details.
15
- #
17
+ #
16
18
  # You should have received a copy of the GNU General Public License along
17
19
  # with pandocomatic. If not, see <http://www.gnu.org/licenses/>.
18
20
  #++
19
21
  module Pandocomatic
22
+ require 'json'
23
+ require 'paru'
24
+ require 'yaml'
25
+
26
+ require_relative './error/pandoc_error'
27
+ require_relative './error/io_error'
28
+ require_relative './pandocomatic_yaml'
29
+
30
+ # Regular expression to find metadata blocks in a string.
31
+ METADATA_BLOCK = /^---[ \t]*(\r\n|\r|\n)(.+?)^(?:---|\.\.\.)[ \t]*(\r\n|\r|\n)/m
32
+
33
+ # PandocMetadata represents the metadata with pandoc options set in
34
+ # templates and input files.
35
+ class PandocMetadata < Hash
36
+ # Extract the YAML metadata from an input string
37
+ #
38
+ # @param input [String] the input string
39
+ # @return [String] the YAML data embedded in the input string
40
+ def self.pandoc2yaml(input)
41
+ extract_metadata(input).first
42
+ end
20
43
 
21
- require 'json'
22
- require 'yaml'
23
- require 'paru'
44
+ # Collect the metadata embedded in the src file and create a new
45
+ # PandocMetadata instance
46
+ #
47
+ # @param src [String] the path to the file to load metadata from
48
+ # @return [PandocMetadata] the metadata in the source file, or an empty
49
+ # one if no such metadata is contained in the source file.
50
+ def self.load_file(src)
51
+ self.load File.read(src), src
52
+ end
24
53
 
25
- require_relative './error/pandoc_error.rb'
26
- require_relative './error/io_error.rb'
27
-
28
- # Regular expression to find metadata blocks in a string.
29
- METADATA_BLOCK = /^---[ \t]*(\r\n|\r|\n)(.+?)^(?:---|\.\.\.)[ \t]*(\r\n|\r|\n)/m
54
+ # Collect the metadata embedded in the src file and create a new
55
+ # PandocMetadata instance
56
+ #
57
+ # @param input [String] the string to load the metadata from
58
+ # @param path [String|Nil] the path to the source of the input, if any
59
+ # @return [PandocMetadata] the metadata in the source file, or an empty
60
+ # one if no such metadata is contained in the source file.
61
+ def self.load(input, path = nil)
62
+ yaml, pandocomatic_blocks = extract_metadata(input, path)
63
+
64
+ if yaml.empty?
65
+ PandocMetadata.new
66
+ else
67
+ PandocMetadata.new PandocomaticYAML.load(yaml, path), unique: pandocomatic_blocks <= 1
68
+ end
69
+ end
30
70
 
31
- # PandocMetadata represents the metadata with pandoc options set in
32
- # templates and input files.
33
- class PandocMetadata < Hash
71
+ # Creat e new PandocMetadata object based on the properties contained
72
+ # in a Hash
73
+ #
74
+ # @param hash [Hash] initial properties for this new PandocMetadata
75
+ # object
76
+ # @param unique [Boolean = true] the pandocomatic property did occur
77
+ # at most once.
78
+ # @return [PandocMetadata]
79
+ def initialize(hash = {}, unique: true)
80
+ super()
81
+ merge! hash
82
+ @unique = unique
83
+ end
34
84
 
35
- # Extract the YAML metadata from an input string
36
- #
37
- # @param input [String] the input string
38
- # @return [String] the YAML data embedded in the input string
39
- def self.pandoc2yaml(input)
40
- extract_metadata(input).first
41
- end
85
+ # Did the metadata contain multiple pandocomatic blocks?
86
+ #
87
+ # @return [Boolean] True if at most one pandocomatic block was present
88
+ # in the metadata
89
+ def unique?
90
+ @unique
91
+ end
42
92
 
43
- # Collect the metadata embedded in the src file and create a new
44
- # PandocMetadata instance
45
- #
46
- # @param src [String] the path to the file to load metadata from
47
- # @return [PandocMetadata] the metadata in the source file, or an empty
48
- # one if no such metadata is contained in the source file.
49
- def self.load_file(src)
50
- load(File.read src)
51
- end
52
-
53
- # Collect the metadata embedded in the src file and create a new
54
- # PandocMetadata instance
55
- #
56
- # @param input [String] the string to load the metadata from
57
- # @return [PandocMetadata] the metadata in the source file, or an empty
58
- # one if no such metadata is contained in the source file.
59
- def self.load(input)
60
- yaml, pandocomatic_blocks = extract_metadata(input)
61
-
62
- if yaml.empty? then
63
- PandocMetadata.new
64
- else
65
- PandocMetadata.new YAML.load(yaml), 1 >= pandocomatic_blocks
66
- end
67
- end
93
+ # Does this PandocMetadata object use a template?
94
+ #
95
+ # @return [Boolean] true if it has a key 'use-template' among the
96
+ # pandocomatic template properties.
97
+ def template?
98
+ pandocomatic? and pandocomatic.key? 'use-template' and !pandocomatic['use-template'].empty?
99
+ end
68
100
 
69
- # Creat e new PandocMetadata object based on the properties contained
70
- # in a Hash
71
- #
72
- # @param hash [Hash] initial properties for this new PandocMetadata
73
- # object
74
- # @param unique [Boolean = true] the pandocomatic property did occur
75
- # at most once.
76
- # @return [PandocMetadata]
77
- def initialize(hash = {}, unique = true)
78
- super()
79
- merge! hash
80
- @unique = unique
101
+ # Get all the templates of this PandocMetadata oject
102
+ #
103
+ # @return [Array] an array of templates used in this PandocMetadata
104
+ # object
105
+ def templates
106
+ if template?
107
+ if pandocomatic['use-template'].is_a? Array
108
+ pandocomatic['use-template']
109
+ else
110
+ [pandocomatic['use-template']]
81
111
  end
112
+ else
113
+ ['']
114
+ end
115
+ end
82
116
 
83
- # Did the metadata contain multiple pandocomatic blocks?
84
- #
85
- # @return [Boolean] True if at most one pandocomatic block was present
86
- # in the metadata
87
- def unique?()
88
- @unique
89
- end
117
+ # Get the used template's name
118
+ #
119
+ # @return [String] the name of the template used, if any, "" otherwise.
120
+ def template_name
121
+ if template?
122
+ pandocomatic['use-template']
123
+ else
124
+ ''
125
+ end
126
+ end
90
127
 
91
- # Does this PandocMetadata object use a template?
92
- #
93
- # @return [Boolean] true if it has a key 'use-template' among the
94
- # pandocomatic template properties.
95
- def has_template?()
96
- has_pandocomatic? and pandocomatic.has_key? 'use-template' and not pandocomatic['use-template'].empty?
97
- end
128
+ # Does this PandocMetadata object have a pandocomatic property?
129
+ #
130
+ # @return [Boolean] True if this PandocMetadata object has a Hash
131
+ # property named "pandocomatic_". False otherwise.
132
+ #
133
+ # Note. For backward compatibility with older versions of
134
+ # pandocomatic, properties named "pandocomatic" (without the trailing
135
+ # underscore) are also accepted.
136
+ def pandocomatic?
137
+ config = nil
138
+ if key?('pandocomatic') || key?('pandocomatic_')
139
+ config = self['pandocomatic'] if key? 'pandocomatic'
140
+ config = self['pandocomatic_'] if key? 'pandocomatic_'
141
+ end
142
+ config.is_a? Hash
143
+ end
98
144
 
99
- # Get all the templates of this PandocMetadata oject
100
- #
101
- # @return [Array] an array of templates used in this PandocMetadata
102
- # object
103
- def templates()
104
- if has_template?
105
- if pandocomatic['use-template'].is_a? Array
106
- pandocomatic['use-template']
107
- else
108
- [pandocomatic['use-template']]
109
- end
110
- else
111
- [""]
112
- end
113
- end
145
+ # Get the pandoc options for this PandocMetadata object
146
+ #
147
+ # @return [Hash] the pandoc options if there are any, an empty Hash
148
+ # otherwise.
149
+ def pandoc_options
150
+ if pandoc_options?
151
+ pandocomatic['pandoc']
152
+ else
153
+ {}
154
+ end
155
+ end
114
156
 
115
- # Get the used template's name
116
- #
117
- # @return [String] the name of the template used, if any, "" otherwise.
118
- def template_name()
119
- if has_template? then
120
- pandocomatic['use-template']
121
- else
122
- ''
123
- end
124
- end
125
-
126
- # Does this PandocMetadata object have a pandocomatic property?
127
- #
128
- # @return [Boolean] True if this PandocMetadata object has a Hash
129
- # property named "pandocomatic_". False otherwise.
130
- #
131
- # Note. For backward compatibility with older versions of
132
- # pandocomatic, properties named "pandocomatic" (without the trailing
133
- # underscore) are also accepted.
134
- def has_pandocomatic?()
135
- config = nil
136
- if has_key? 'pandocomatic' or has_key? 'pandocomatic_'
137
- config = self['pandocomatic'] if has_key? 'pandocomatic'
138
- config = self['pandocomatic_'] if has_key? 'pandocomatic_'
139
- end
140
- config.is_a? Hash
141
- end
157
+ # Get the pandocomatic property of this PandocMetadata object
158
+ #
159
+ # @return [Hash] the pandocomatic property as a Hash, if any, an empty
160
+ # Hash otherwise.
161
+ def pandocomatic
162
+ return self['pandocomatic'] if key? 'pandocomatic'
163
+ return self['pandocomatic_'] if key? 'pandocomatic_'
164
+ end
142
165
 
143
- # Get the pandoc options for this PandocMetadata object
144
- #
145
- # @return [Hash] the pandoc options if there are any, an empty Hash
146
- # otherwise.
147
- def pandoc_options()
148
- if has_pandoc_options? then
149
- pandocomatic['pandoc']
150
- else
151
- {}
152
- end
153
- end
166
+ # Does this PandocMetadata object has a pandoc options property?
167
+ #
168
+ # @return [Boolean] True if there is a pandoc options property in this
169
+ # PandocMetadata object. False otherwise.
170
+ def pandoc_options?
171
+ pandocomatic? and pandocomatic.key? 'pandoc' and !pandocomatic['pandoc'].nil?
172
+ end
154
173
 
155
- # Get the pandocomatic property of this PandocMetadata object
156
- #
157
- # @return [Hash] the pandocomatic property as a Hash, if any, an empty
158
- # Hash otherwise.
159
- def pandocomatic()
160
- return self['pandocomatic'] if has_key? 'pandocomatic'
161
- return self['pandocomatic_'] if has_key? 'pandocomatic_'
162
- end
174
+ # Extract the metadata from an input file
175
+ #
176
+ # @param input [String] the string to extract metadata from
177
+ # @return [Array] The return value is an array with the following two
178
+ # values:
179
+ #
180
+ # 1. The extracted metadata as a YAML string
181
+ # 2. The number of times the pandocomatic properties did occur in the
182
+ # input.
183
+ #
184
+ # If more than one pandocomatic property is contained in the input,
185
+ # all but the first are discarded and are not present in the
186
+ # extracted metadata YAML string.
187
+ private_class_method def self.extract_metadata(input, path)
188
+ metadata_blocks = MetadataBlockList.new input, path
189
+
190
+ ["#{YAML.dump(metadata_blocks.full)}...", metadata_blocks.count_pandocomatic_blocks]
191
+ end
163
192
 
164
- # Does this PandocMetadata object has a pandoc options property?
165
- #
166
- # @return [Boolean] True if there is a pandoc options property in this
167
- # PandocMetadata object. False otherwise.
168
- def has_pandoc_options?()
169
- has_pandocomatic? and pandocomatic.has_key? 'pandoc' and not pandocomatic['pandoc'].nil?
193
+ # List of YAML metadata blocks present in some input source file
194
+ class MetadataBlockList
195
+ def initialize(input, path)
196
+ @metadata_blocks = input
197
+ .scan(METADATA_BLOCK)
198
+ .map { |match| PandocomaticYAML.load "---#{match.join}...", path }
199
+ .select { |block| !block.nil? and !block.empty? }
200
+ end
201
+
202
+ # Count the number of metadata blocks with a "pandocomatic_" property.
203
+ def count_pandocomatic_blocks
204
+ @metadata_blocks.count do |block|
205
+ block.key? 'pandocomatic_' or block.key? 'pandocomatic'
170
206
  end
171
-
172
- private
173
-
174
- # Extract the metadata from an input file
175
- #
176
- # @param input [String] the string to extract metadata from
177
- # @return [Array] The return value is an array with the following two
178
- # values:
179
- #
180
- # 1. The extracted metadata as a YAML string
181
- # 2. The number of times the pandocomatic properties did occur in the
182
- # input.
207
+ end
208
+
209
+ # Combine all metadata blocks into a single metadata block
210
+ # @return [Hash]
211
+ def full
212
+ # According to the pandoc manual: "A document may contain multiple
213
+ # metadata blocks. The metadata fields will be combined through a
214
+ # left-biased union: if two metadata blocks attempt to set the
215
+ # same field, the value from the first block will be taken."
183
216
  #
184
- # If more than one pandocomatic property is contained in the input,
185
- # all but the first are discarded and are not present in the
186
- # extracted metadata YAML string.
187
- def self.extract_metadata(input)
188
- metadata_blocks = input
189
- .scan(METADATA_BLOCK)
190
- .map {|match| YAML.load "---#{match.join()}..."}
191
- .select {|block| not block.nil? and not block.empty?}
192
-
193
- pandocomatic_blocks = metadata_blocks.count do |block|
194
- block.key? "pandocomatic_" or block.key? "pandocomatic"
195
- end
196
-
197
- # According to the pandoc manual: "A document may contain multiple
198
- # metadata blocks. The metadata fields will be combined through a
199
- # left-biased union: if two metadata blocks attempt to set the
200
- # same field, the value from the first block will be taken."
201
- #
202
- # Here we do the same
203
- full_metadata = metadata_blocks
204
- .reverse
205
- .reduce(Hash.new) {|metadata, block| metadata.merge!(block)}
206
-
207
- yaml_string = YAML.dump(full_metadata) + "..."
208
-
209
- return [yaml_string, pandocomatic_blocks]
210
- end
211
-
217
+ # Here we do the same
218
+ @metadata_blocks
219
+ .reverse
220
+ .reduce({}) { |metadata, block| metadata.merge!(block) }
221
+ end
212
222
  end
213
223
 
224
+ private_constant :MetadataBlockList
225
+ end
214
226
  end