paru 0.2.5c → 0.2.5f

Sign up to get free protection for your applications and to get access to all the features.
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