pandocomatic 0.2.8 → 1.0.0

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.
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