paru 0.2.5c → 0.2.5f

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/bin/do-pandoc.rb +5 -5
  3. data/bin/pandoc2yaml.rb +23 -58
  4. data/lib/paru.rb +1 -5
  5. data/lib/paru/error.rb +0 -2
  6. data/lib/paru/filter.rb +46 -30
  7. data/lib/paru/filter/ast_manipulation.rb +0 -1
  8. data/lib/paru/filter/attr.rb +0 -1
  9. data/lib/paru/filter/block.rb +2 -2
  10. data/lib/paru/filter/block_quote.rb +2 -2
  11. data/lib/paru/filter/bullet_list.rb +2 -2
  12. data/lib/paru/filter/citation.rb +2 -2
  13. data/lib/paru/filter/cite.rb +8 -4
  14. data/lib/paru/filter/code.rb +11 -3
  15. data/lib/paru/filter/code_block.rb +5 -3
  16. data/lib/paru/filter/definition_list.rb +2 -2
  17. data/lib/paru/filter/definition_list_item.rb +4 -4
  18. data/lib/paru/filter/div.rb +5 -3
  19. data/lib/paru/filter/document.rb +47 -16
  20. data/lib/paru/filter/emph.rb +2 -2
  21. data/lib/paru/filter/empty_block.rb +3 -3
  22. data/lib/paru/filter/empty_inline.rb +2 -2
  23. data/lib/paru/filter/header.rb +6 -3
  24. data/lib/paru/filter/horizontal_rule.rb +6 -6
  25. data/lib/paru/filter/image.rb +2 -3
  26. data/lib/paru/filter/inline.rb +5 -2
  27. data/lib/paru/filter/inner_markdown.rb +85 -0
  28. data/lib/paru/filter/line_block.rb +8 -2
  29. data/lib/paru/filter/line_break.rb +2 -2
  30. data/lib/paru/filter/link.rb +4 -5
  31. data/lib/paru/filter/list.rb +8 -6
  32. data/lib/paru/filter/math.rb +2 -2
  33. data/lib/paru/filter/meta.rb +15 -4
  34. data/lib/paru/filter/meta_blocks.rb +2 -2
  35. data/lib/paru/filter/meta_bool.rb +2 -3
  36. data/lib/paru/filter/meta_inlines.rb +4 -2
  37. data/lib/paru/filter/meta_list.rb +2 -3
  38. data/lib/paru/filter/meta_map.rb +10 -142
  39. data/lib/paru/filter/meta_string.rb +1 -1
  40. data/lib/paru/filter/meta_value.rb +5 -4
  41. data/lib/paru/filter/metadata.rb +114 -0
  42. data/lib/paru/filter/node.rb +130 -11
  43. data/lib/paru/filter/note.rb +3 -4
  44. data/lib/paru/filter/null.rb +2 -2
  45. data/lib/paru/filter/ordered_list.rb +5 -5
  46. data/lib/paru/filter/para.rb +4 -2
  47. data/lib/paru/filter/plain.rb +4 -2
  48. data/lib/paru/filter/quoted.rb +2 -2
  49. data/lib/paru/filter/raw_block.rb +5 -3
  50. data/lib/paru/filter/raw_inline.rb +2 -3
  51. data/lib/paru/filter/small_caps.rb +2 -2
  52. data/lib/paru/filter/soft_break.rb +2 -2
  53. data/lib/paru/filter/space.rb +2 -2
  54. data/lib/paru/filter/span.rb +3 -4
  55. data/lib/paru/filter/str.rb +2 -2
  56. data/lib/paru/filter/strikeout.rb +2 -2
  57. data/lib/paru/filter/strong.rb +2 -2
  58. data/lib/paru/filter/subscript.rb +2 -2
  59. data/lib/paru/filter/superscript.rb +2 -2
  60. data/lib/paru/filter/table.rb +3 -3
  61. data/lib/paru/filter/table_row.rb +2 -2
  62. data/lib/paru/filter/target.rb +0 -1
  63. data/lib/paru/filter/version.rb +2 -2
  64. data/lib/paru/filter_error.rb +25 -0
  65. data/lib/paru/pandoc.rb +3 -4
  66. data/lib/paru/pandoc2yaml.rb +71 -0
  67. data/lib/paru/selector.rb +2 -4
  68. metadata +6 -3
  69. data/lib/paru/filter/markdown.rb +0 -150
@@ -16,32 +16,34 @@
16
16
  # You should have received a copy of the GNU General Public License
17
17
  # along with Paru. If not, see <http://www.gnu.org/licenses/>.
18
18
  #++
19
+ require_relative "./block.rb"
20
+ require_relative "./inline.rb"
21
+
19
22
  module Paru
20
23
  module PandocFilter
21
- require_relative "./block"
22
-
23
24
  # A List node is a base node for various List node types
24
25
  class List < Block
25
26
 
26
27
  # Create a new List node based on contents
27
28
  #
28
29
  # @param contents [Array] the contents of the list
29
- def initialize contents
30
+ # @param node_class [Node = PandocFilter::Block] the contents are {Inline} nodes
31
+ def initialize(contents, node_class = Block)
30
32
  super []
31
33
  contents.each do |item|
32
- @children.push Block.new item
34
+ @children.push node_class.new item
33
35
  end
34
36
  end
35
37
 
36
38
  # Create an AST representation of this List node
37
- def ast_contents
39
+ def ast_contents()
38
40
  @children.map {|child| child.ast_contents}
39
41
  end
40
42
 
41
43
  # Has this List node block contents?
42
44
  #
43
45
  # @return [Boolean] true
44
- def has_block?
46
+ def has_block?()
45
47
  true
46
48
  end
47
49
  end
@@ -16,10 +16,10 @@
16
16
  # You should have received a copy of the GNU General Public License
17
17
  # along with Paru. If not, see <http://www.gnu.org/licenses/>.
18
18
  #++
19
+ require_relative "./inline.rb"
20
+
19
21
  module Paru
20
22
  module PandocFilter
21
- require_relative "./inline"
22
-
23
23
  # A Math Inline node with the type of math node and the mathematical
24
24
  # contents
25
25
  #
@@ -16,16 +16,15 @@
16
16
  # You should have received a copy of the GNU General Public License
17
17
  # along with Paru. If not, see <http://www.gnu.org/licenses/>.
18
18
  #++
19
+ require_relative "./meta_map.rb"
20
+
19
21
  module Paru
20
22
  module PandocFilter
21
- require_relative "./meta_map"
22
-
23
23
  # A Meta node represents the metadata of a document. It is a MetaMap
24
24
  # node.
25
25
  #
26
26
  # @see http://hackage.haskell.org/package/pandoc-types-1.17.0.4/docs/Text-Pandoc-Definition.html#t:Meta
27
27
  class Meta < MetaMap
28
-
29
28
  # The type of a Meta is "meta"
30
29
  #
31
30
  # @return [String] "meta"
@@ -42,11 +41,23 @@ module Paru
42
41
  #
43
42
  # @return [MetaMap] a MetaMap representation of this metadata
44
43
  def to_meta_map()
45
- map = MetaMap.new []
44
+ map = MetaMap.new
46
45
  map.children = @children
47
46
  map
48
47
  end
49
48
 
49
+ # Convert a {MetaMap} node to a {Meta} node
50
+ #
51
+ # @param meta_map [MetaMap] the {MetaMap} node to convert to a
52
+ # {Meta} node.
53
+ #
54
+ # @return [Meta]
55
+ def self.from_meta_map(meta_map)
56
+ meta = Meta.new {}
57
+ meta.children = meta_map.children unless meta_map.children.nil? or meta_map.children.empty?
58
+ meta
59
+ end
60
+
50
61
  end
51
62
  end
52
63
  end
@@ -16,10 +16,10 @@
16
16
  # You should have received a copy of the GNU General Public License
17
17
  # along with Paru. If not, see <http://www.gnu.org/licenses/>.
18
18
  #++
19
+ require_relative "./node.rb"
20
+
19
21
  module Paru
20
22
  module PandocFilter
21
- require_relative "./node"
22
-
23
23
  # A MetaBlocks Node contains a list of {Block} nodes
24
24
  class MetaBlocks < Node
25
25
  end
@@ -16,11 +16,10 @@
16
16
  # You should have received a copy of the GNU General Public License
17
17
  # along with Paru. If not, see <http://www.gnu.org/licenses/>.
18
18
  #++
19
+ require_relative "./meta_value.rb"
20
+
19
21
  module Paru
20
22
  module PandocFilter
21
-
22
- require_relative "./meta_value"
23
-
24
23
  # A MetaBool Note representa a Boolean value
25
24
  class MetaBool < MetaValue
26
25
  end
@@ -16,12 +16,14 @@
16
16
  # You should have received a copy of the GNU General Public License
17
17
  # along with Paru. If not, see <http://www.gnu.org/licenses/>.
18
18
  #++
19
+ require_relative "./node.rb"
20
+ require_relative "./inner_markdown.rb"
21
+
19
22
  module Paru
20
23
  module PandocFilter
21
- require_relative "./node"
22
-
23
24
  # A MetaInlines node contains a list of {Inline} nodes
24
25
  class MetaInlines < Node
26
+ include InnerMarkdown
25
27
  end
26
28
  end
27
29
  end
@@ -16,11 +16,10 @@
16
16
  # You should have received a copy of the GNU General Public License
17
17
  # along with Paru. If not, see <http://www.gnu.org/licenses/>.
18
18
  #++
19
+ require_relative "./node.rb"
20
+
19
21
  module Paru
20
22
  module PandocFilter
21
-
22
- require_relative "./node"
23
-
24
23
  # A MetaList node contains a list of MetaValue nodes
25
24
  class MetaList < Node
26
25
  end
@@ -16,20 +16,21 @@
16
16
  # You should have received a copy of the GNU General Public License
17
17
  # along with Paru. If not, see <http://www.gnu.org/licenses/>.
18
18
  #++
19
- module Paru
20
- module PandocFilter
19
+ require_relative "./node.rb"
21
20
 
22
- require_relative "./node"
23
- require_relative "../pandoc.rb"
21
+ require_relative "../pandoc.rb"
24
22
 
23
+ module Paru
24
+ module PandocFilter
25
25
  # A MetaMap Node is a map of String keys with MetaValue values
26
26
  class MetaMap < Node
27
27
  include Enumerable
28
28
 
29
29
  # Create a new MetaMap based on the contents
30
30
  #
31
- # @param contents [Array] a list of key-value pairs
32
- def initialize(contents)
31
+ # @param contents [Hash = {}] a list of key-value pairs, defaults
32
+ # to an empty hash
33
+ def initialize(contents = {})
33
34
  @children = Hash.new
34
35
 
35
36
  if contents.is_a? Hash
@@ -41,8 +42,7 @@ module Paru
41
42
  end
42
43
  end
43
44
 
44
- # Get the value belonging to key. Prefer to use the {has?}, {get},
45
- # {replace} and {delete} methods to manipulate metadata.
45
+ # Get the value belonging to key.
46
46
  #
47
47
  # @param key [String] the key
48
48
  #
@@ -51,9 +51,7 @@ module Paru
51
51
  @children[key]
52
52
  end
53
53
 
54
- # Set a value with a key. It is easier to use the {yaml} method to set
55
- # metadata properties; the {yaml} method is the preferred method
56
- # to set the metadata.
54
+ # Set a value with a key.
57
55
  #
58
56
  # @param key [String] the key to set
59
57
  # @param value [MetaBlocks|MetaBool|MetaInlines|MetaList|MetaMap|MetaString|MetaValue] the value to set
@@ -67,146 +65,16 @@ module Paru
67
65
  yield(key, value)
68
66
  end
69
67
  end
70
-
71
- # Mixin the YAML code into this metadata object
72
- #
73
- # @param yaml_string [YAML] A string with YAML data
74
- # @return [MetaMap] this MetaMap object
75
- #
76
- # @example Set some properties in the metadata
77
- # #!/usr/bin/env ruby
78
- # require "paru/filter"
79
- # require "date"
80
- #
81
- # Paru::Filter.run do
82
- # metadata.yaml <<~YAML
83
- # ---
84
- # date: #{Date.today.to_s}
85
- # title: This **is** the title
86
- # pandoc_options:
87
- # from: markdown
88
- # toc: true
89
- # keywords:
90
- # - metadata
91
- # - pandoc
92
- # - filter
93
- # ...
94
- # YAML
95
- # end
96
- #
97
- def yaml(yaml_string)
98
- meta_from_yaml(yaml_string).each do |key, value|
99
- self[key] = value
100
- end
101
- self
102
- end
103
-
104
- # Replace the property in this MetaMap matching the selector with
105
- # metadata specified by second parameter. If that parameter is a
106
- # String, it is treated as a YAML string.
107
- #
108
- # @param selector [String] a dot-separated sequence of property
109
- # names denoting a sequence of descendants.
110
- #
111
- # @param value [MetaBlocks|MetaBool|MetaInlines|MetaList|MetaMap|MetaString|MetaValue|String]
112
- # if value is a String, it is treated as a yaml string
113
- def replace(selector, value)
114
- parent = select(selector, true)
115
- if value.is_a? String
116
- value = meta_from_yaml(value)
117
- end
118
- parent.children[last_key(selector)] = value
119
- end
120
-
121
- # Get the property in this MetaMap matching the selector
122
- #
123
- # @param selector [String] a dot-separated sequence of property
124
- # names denoting a sequence of descendants.
125
- #
126
- # @return [MetaBlocks|MetaBool|MetaInlines|MetaList|MetaMap|MetaString|MetaValue] the value matching the selected property, nil if it cannot be found
127
- def get(selector)
128
- select(selector)
129
- end
130
-
131
- # Has this MetaMap a descendant matching selector?
132
- #
133
- # @param selector [String] a dot-separated sequence of property
134
- # names denoting a sequence of descendants
135
- #
136
- # @return [Boolean] True if this MetaMap contains a descendant
137
- # matching selector, false otherwise
138
- def has?(selector)
139
- not select(selector).nil?
140
- end
141
-
142
- # Delete the property in this MetaMap that matches the selector
143
- #
144
- # @param selector [String] a dot-separated sequence of property
145
- # names denoting a sequence of descendants
146
- #
147
- # @return [MetaBlocks|MetaBool|MetaInlines|MetaList|MetaMap|MetaString|MetaValue] the value of the deleted property, nil if it cannot be found
148
- #
149
- def delete(selector)
150
- parent = select(selector, true)
151
- parent.children.delete(last_key(selector))
152
- end
153
68
 
154
69
  # The AST contents
155
70
  def ast_contents()
156
71
  ast = Hash.new
157
72
  @children.each_pair do |key, value|
158
73
  ast[key] = value.to_ast
159
- end
74
+ end if @children.is_a? Hash
160
75
  ast
161
76
  end
162
-
163
- private
164
-
165
- # Select a node given a selector as a dot separated sequence of
166
- # descendant names.
167
- #
168
- # @param selector [String] Dot separated sequence of property
169
- # names
170
- #
171
- # @param get_parent [Boolean = false] Get the parent MetaMap
172
- # of the selected property instead of its value
173
- #
174
- # @return [MetaBlocks|MetaBool|MetaInlines|MetaList|MetaMap|MetaString|MetaValue] the value of the deleted property, nil if it cannot be found
175
- def select(selector, get_parent = false)
176
- keys = selector.split(".")
177
- level = self
178
-
179
- while not keys.empty?
180
- key = keys.shift
181
- if not level.children.has_key? key
182
- return nil
183
- else
184
- if get_parent and keys.empty?
185
- return level
186
- else
187
- level = level[key]
188
- end
189
- end
190
- end
191
-
192
- level
193
- end
194
-
195
- # Get the last key in this selector
196
- def last_key(selector)
197
- selector.split(".").last
198
- end
199
77
 
200
- # Convert a yaml string to a MetaMap
201
- def meta_from_yaml(yaml_string)
202
- json_string = Pandoc.new do
203
- from "markdown"
204
- to "json"
205
- end << yaml_string
206
-
207
- meta_doc = PandocFilter::Document.from_JSON json_string
208
- meta_doc.meta.to_meta_map
209
- end
210
78
  end
211
79
  end
212
80
  end
@@ -19,7 +19,7 @@
19
19
  module Paru
20
20
  module PandocFilter
21
21
 
22
- require_relative "./meta_value"
22
+ require_relative "./meta_value.rb"
23
23
 
24
24
  # A MetaString Node represents a String value
25
25
  class MetaString < MetaValue
@@ -16,18 +16,19 @@
16
16
  # You should have received a copy of the GNU General Public License
17
17
  # along with Paru. If not, see <http://www.gnu.org/licenses/>.
18
18
  #++
19
+ require_relative "./node.rb"
20
+ require_relative "./inner_markdown.rb"
21
+
19
22
  module Paru
20
23
  module PandocFilter
21
-
22
- require_relative "./node"
23
-
24
24
  # A MetaValue Node is either a MetaMap, MetaList, MetaBool, MetaString, MetaInlines, or a MetaBlocks.
25
25
  #
26
26
  # @see http://hackage.haskell.org/package/pandoc-types-1.17.0.4/docs/Text-Pandoc-Definition.html#t:MetaValue
27
27
  #
28
28
  # @!attribute value
29
- # @return [String]
29
+ # @return [String|Boolean]
30
30
  class MetaValue < Node
31
+ include InnerMarkdown
31
32
 
32
33
  attr_accessor :value
33
34
 
@@ -0,0 +1,114 @@
1
+ #--
2
+ # Copyright 2015, 2016, 2017 Huub de Beer <Huub@heerdebeer.org>
3
+ #
4
+ # This file is part of Paru
5
+ #
6
+ # Paru is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Paru is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Paru. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+ require "yaml"
20
+ require_relative "../pandoc.rb"
21
+ require_relative "../filter_error.rb"
22
+
23
+ module Paru
24
+ module PandocFilter
25
+ # A Metadata object is a Ruby Hash representation of a pandoc metadata
26
+ # node.
27
+ class Metadata < Hash
28
+
29
+ # Create a new Metadata object based on the contents.
30
+ #
31
+ # @param contents [MetaMap|String|Hash] the initial contents of this
32
+ # metadata. If contents is a String, it is treated as a YAML string
33
+ # and converted to a Hash first.
34
+ #
35
+ # @raise Error when converting contents to a Hash fails
36
+ def initialize(contents = {})
37
+ if not contents.is_a? Hash
38
+ # If not a Hash, it is either a YAML string or can be
39
+ # converted to a YAML string
40
+ if contents.is_a? PandocFilter::MetaMap
41
+ yaml_string = meta2yaml contents
42
+ elsif contents.is_a? String
43
+ yaml_string = contents
44
+ else
45
+ raise FilterError.new("Expected a Hash, MetaMap, or String, got '#{contents}' instead.")
46
+ end
47
+
48
+ # Try to convert the YAML string to a Hash
49
+ if yaml_string.empty?
50
+ contents = {}
51
+ else
52
+ contents = YAML.load yaml_string
53
+ end
54
+
55
+ if not contents
56
+ # Error parsing YAML
57
+ raise FilterError.new("Unable to convert YAML string '#{yaml_string}' to a Hash.")
58
+ end
59
+ end
60
+
61
+ # Merge the contents with this newly created Metadata
62
+ contents.each do |key, value|
63
+ self[key] = value
64
+ end
65
+ end
66
+
67
+ # Convert this Metadata to a pandoc AST representation of
68
+ # metadata: {PandocFilter::Meta}
69
+ #
70
+ # @return [Meta] the pandoc AST representation as a {PandocFilter::Meta} node
71
+ def to_meta()
72
+ if self.empty?
73
+ PandocFilter::Meta.new {}
74
+ else
75
+ begin
76
+ yaml_string = "#{clean_hash.to_yaml}..."
77
+ yaml2json = Paru::Pandoc.new {from "markdown"; to "json"}
78
+ json_string = yaml2json << yaml_string
79
+ meta_doc = PandocFilter::Document.from_JSON json_string
80
+ meta_doc.meta
81
+ rescue
82
+ end
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ # Convert a {PandocFilter::Meta} node to a Metadata
89
+ #
90
+ # @param meta [Meta|MetaMap] the {PandocFilter::Meta} node to convert to a
91
+ # MetadataHash
92
+ def meta2yaml(meta)
93
+ begin
94
+ json2yaml = Paru::Pandoc.new {from "json"; to "markdown"; standalone}
95
+ meta = PandocFilter::Meta.from_meta_map(meta) unless meta.is_a? PandocFilter::Meta
96
+ meta_doc = PandocFilter::Document.new(PandocFilter::CURRENT_PANDOC_VERSION, meta.to_ast, [])
97
+ yaml_string = json2yaml << meta_doc.to_JSON
98
+ yaml_string.strip
99
+ rescue
100
+ end
101
+ end
102
+
103
+ # Create a true Hash from this Metadata to prevent the +to_yaml+
104
+ # method from mixing in the name of this class and confusing pandoc
105
+ def clean_hash
106
+ hash = {}
107
+ each do |key, value|
108
+ hash[key] = value
109
+ end
110
+ hash
111
+ end
112
+ end
113
+ end
114
+ end