paru 0.2.4.2 → 0.2.4.3
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 +4 -4
- data/lib/paru.rb +8 -20
- data/lib/paru/error.rb +4 -6
- data/lib/paru/filter.rb +144 -110
- data/lib/paru/filter/ast_manipulation.rb +75 -39
- data/lib/paru/filter/attr.rb +72 -36
- data/lib/paru/filter/block.rb +14 -8
- data/lib/paru/filter/block_quote.rb +12 -9
- data/lib/paru/filter/bullet_list.rb +6 -6
- data/lib/paru/filter/citation.rb +51 -25
- data/lib/paru/filter/cite.rb +29 -20
- data/lib/paru/filter/code.rb +41 -24
- data/lib/paru/filter/code_block.rb +36 -21
- data/lib/paru/filter/definition_list.rb +19 -15
- data/lib/paru/filter/definition_list_item.rb +30 -17
- data/lib/paru/filter/div.rb +29 -21
- data/lib/paru/filter/document.rb +73 -46
- data/lib/paru/filter/emph.rb +6 -6
- data/lib/paru/filter/empty_block.rb +17 -13
- data/lib/paru/filter/empty_inline.rb +24 -17
- data/lib/paru/filter/header.rb +38 -23
- data/lib/paru/filter/image.rb +13 -11
- data/lib/paru/filter/inline.rb +21 -10
- data/lib/paru/filter/line_block.rb +6 -6
- data/lib/paru/filter/line_break.rb +6 -6
- data/lib/paru/filter/link.rb +33 -21
- data/lib/paru/filter/list.rb +26 -17
- data/lib/paru/filter/list_attributes.rb +53 -32
- data/lib/paru/filter/markdown.rb +102 -59
- data/lib/paru/filter/math.rb +65 -38
- data/lib/paru/filter/meta.rb +26 -16
- data/lib/paru/filter/meta_blocks.rb +12 -9
- data/lib/paru/filter/meta_bool.rb +6 -6
- data/lib/paru/filter/meta_inlines.rb +12 -9
- data/lib/paru/filter/meta_list.rb +6 -6
- data/lib/paru/filter/meta_map.rb +49 -33
- data/lib/paru/filter/meta_string.rb +6 -6
- data/lib/paru/filter/meta_value.rb +22 -14
- data/lib/paru/filter/node.rb +204 -129
- data/lib/paru/filter/note.rb +31 -20
- data/lib/paru/filter/null.rb +6 -6
- data/lib/paru/filter/ordered_list.rb +34 -18
- data/lib/paru/filter/para.rb +20 -13
- data/lib/paru/filter/plain.rb +21 -12
- data/lib/paru/filter/quoted.rb +27 -18
- data/lib/paru/filter/raw_block.rb +32 -19
- data/lib/paru/filter/raw_inline.rb +40 -22
- data/lib/paru/filter/small_caps.rb +7 -6
- data/lib/paru/filter/soft_break.rb +6 -6
- data/lib/paru/filter/space.rb +6 -6
- data/lib/paru/filter/span.rb +28 -18
- data/lib/paru/filter/str.rb +29 -18
- data/lib/paru/filter/strikeout.rb +6 -6
- data/lib/paru/filter/strong.rb +6 -6
- data/lib/paru/filter/subscript.rb +6 -6
- data/lib/paru/filter/superscript.rb +6 -6
- data/lib/paru/filter/table.rb +51 -29
- data/lib/paru/filter/table_row.rb +21 -14
- data/lib/paru/filter/target.rb +29 -15
- data/lib/paru/filter/version.rb +23 -14
- data/lib/paru/pandoc.rb +165 -111
- data/lib/paru/pandoc_options.yaml +3 -3
- data/lib/paru/selector.rb +176 -153
- metadata +2 -3
- data/lib/paru/filter/alignment.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1b0bdd09190def2f416be363cec8c5dc2e51106
|
4
|
+
data.tar.gz: fb2184d30afb43207c81ce1a681b39a58dea2343
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 006cfa8e6e18ad4ee4596c27e23bac083a8afa820e0e31744632417f1e2d9beae70047623b8db4a01b64ad28823e746cc4c8b9fbd10ad6c9326dd9b731c15224
|
7
|
+
data.tar.gz: ee5d944ce20ba48171b51f6700587c7cb264f0c7a8ea807fcc51002e642980a6823b30dbb5c652fa9051cbfb74fa1d68fabcbd51d0811147d62c1cf9558753c0
|
data/lib/paru.rb
CHANGED
@@ -1,19 +1,5 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
# Paru is a simple Ruby wrapper around {pandoc}[http://www.pandoc.org], the
|
4
|
-
# great multi-format document converter. Paru supports automating pandoc by
|
5
|
-
# writing Ruby programs and using pandoc in your Ruby programs. Paru also
|
6
|
-
# supports writing pandoc filters in Ruby. In {paru's user
|
7
|
-
# manual}[https://heerdebeer.org/Software/markdown/paru/] the use of paru is
|
8
|
-
# explained in detail, from explaining how to install and use paru, creating
|
9
|
-
# and using filters, to putting it all together in a real-world use case like
|
10
|
-
# generating that manual page.
|
11
|
-
#
|
12
|
-
# This document, however, describes paru's API.
|
13
|
-
#
|
14
|
-
# == Licence
|
15
|
-
#
|
16
|
-
# Copyright 2015, 2016 Huub de Beer <Huub@heerdebeer.org>
|
1
|
+
#--
|
2
|
+
# Copyright 2015, 2016, 2017 Huub de Beer <Huub@heerdebeer.org>
|
17
3
|
#
|
18
4
|
# This file is part of Paru
|
19
5
|
#
|
@@ -29,7 +15,9 @@
|
|
29
15
|
#
|
30
16
|
# You should have received a copy of the GNU General Public License along with
|
31
17
|
# Paru. If not, see <http://www.gnu.org/licenses/>.
|
32
|
-
|
33
|
-
|
34
|
-
require "paru/
|
35
|
-
require "paru/
|
18
|
+
#++
|
19
|
+
module Paru
|
20
|
+
require "paru/pandoc"
|
21
|
+
require "paru/error"
|
22
|
+
require "paru/filter"
|
23
|
+
end
|
data/lib/paru/error.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright 2015, 2016 Huub de Beer <Huub@heerdebeer.org>
|
2
|
+
# Copyright 2015, 2016, 2017 Huub de Beer <Huub@heerdebeer.org>
|
3
3
|
#
|
4
4
|
# This file is part of Paru
|
5
5
|
#
|
@@ -19,9 +19,7 @@
|
|
19
19
|
|
20
20
|
module Paru
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
class Error < RuntimeError
|
26
|
-
end
|
22
|
+
# An error class to use as a basis for paru specific errors.
|
23
|
+
class Error < RuntimeError
|
24
|
+
end
|
27
25
|
end
|
data/lib/paru/filter.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright 2015, 2016 Huub de Beer <Huub@heerdebeer.org>
|
2
|
+
# Copyright 2015, 2016, 2017 Huub de Beer <Huub@heerdebeer.org>
|
3
3
|
#
|
4
4
|
# This file is part of Paru
|
5
5
|
#
|
@@ -16,117 +16,151 @@
|
|
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
|
-
|
20
19
|
module Paru
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
#
|
87
|
-
#
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
end
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
21
|
+
require_relative "./selector"
|
22
|
+
require_relative "filter/document"
|
23
|
+
|
24
|
+
# Paru filter is a wrapper around pandoc's JSON api, which is based on
|
25
|
+
# {pandoc-types}[https://hackage.haskell.org/package/pandoc-types-1.17.0.4/docs/Text-Pandoc-Definition.html].
|
26
|
+
# Pandoc treats block elements and inline elements differently.
|
27
|
+
#
|
28
|
+
# Pandoc's block elements are:
|
29
|
+
PANDOC_BLOCK = [
|
30
|
+
"Plain",
|
31
|
+
"Para",
|
32
|
+
"LineBlock",
|
33
|
+
"CodeBlock",
|
34
|
+
"RawBlock",
|
35
|
+
"BlockQuote",
|
36
|
+
"OrderedList",
|
37
|
+
"BulletList",
|
38
|
+
"DefinitionList",
|
39
|
+
"Header",
|
40
|
+
"HorizontalRule",
|
41
|
+
"Table",
|
42
|
+
"Div",
|
43
|
+
"Null"
|
44
|
+
]
|
45
|
+
|
46
|
+
# Pandoc's inline elements are
|
47
|
+
PANDOC_INLINE = [
|
48
|
+
"Str",
|
49
|
+
"Emph",
|
50
|
+
"Strong",
|
51
|
+
"Strikeout",
|
52
|
+
"Superscript",
|
53
|
+
"Subscript",
|
54
|
+
"SmallCaps",
|
55
|
+
"Quoted",
|
56
|
+
"Cite",
|
57
|
+
"Space",
|
58
|
+
"SoftBreak",
|
59
|
+
"LineBreak",
|
60
|
+
"Math",
|
61
|
+
"RawInline",
|
62
|
+
"Link",
|
63
|
+
"Image",
|
64
|
+
"Note",
|
65
|
+
"Span"
|
66
|
+
]
|
67
|
+
|
68
|
+
# All of pandoc's type together:
|
69
|
+
PANDOC_TYPES = PANDOC_BLOCK + PANDOC_INLINE
|
70
|
+
|
71
|
+
|
72
|
+
# Filter is used to write your own pandoc filter in Ruby. A Filter is
|
73
|
+
# almost always created and immediately executed via the +run+ method as
|
74
|
+
# shown in the following examples:
|
75
|
+
#
|
76
|
+
# @example Identity filter
|
77
|
+
# Paru::Filter.run do
|
78
|
+
# # nothing
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# @example Remove horizontal lines
|
82
|
+
# Paru::Filter.run do
|
83
|
+
# with "HorizontalRule" do |rule|
|
84
|
+
# if rule.has_parent? then
|
85
|
+
# rule.parent.delete rule
|
86
|
+
# else
|
87
|
+
# rule.outer_markdown = ""
|
88
|
+
# end
|
89
|
+
# end
|
90
|
+
# end
|
91
|
+
class Filter
|
92
|
+
|
93
|
+
# Run the filter specified by block. In the block you specify
|
94
|
+
# selectors and actions to be performed on selected nodes. In the
|
95
|
+
# example below, the selector is "Image", which selects all image
|
96
|
+
# nodes. The action is to prepend the contents of the image's caption
|
97
|
+
# by the string "Figure. ".
|
98
|
+
#
|
99
|
+
# @param block [Proc] the filter specification
|
100
|
+
#
|
101
|
+
# @example Add 'Figure' to each image's caption
|
102
|
+
# Paru::Filter.run do
|
103
|
+
# with "Image" do |image|
|
104
|
+
# image.inner_markdown = "Figure. #{image.inner_markdown}"
|
105
|
+
# end
|
106
|
+
# end
|
107
|
+
def self.run(&block)
|
108
|
+
Filter.new().filter(&block)
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
# The Document node from JSON formatted pandoc document structure
|
113
|
+
# on STDIN that is being filtered
|
114
|
+
#
|
115
|
+
# @return [Document] create a new Document node from a pandoc AST from
|
116
|
+
# JSON from STDIN
|
117
|
+
def document()
|
118
|
+
PandocFilter::Document.from_JSON $stdin.read
|
119
|
+
end
|
120
|
+
|
121
|
+
# Create a filter using +block+.
|
122
|
+
#
|
123
|
+
# @param block [Proc] a block specifying selectors and actions
|
124
|
+
# @return [JSON] a JSON string with the filtered pandoc AST
|
125
|
+
def filter(&block)
|
126
|
+
@selectors = Hash.new
|
127
|
+
@filtered_nodes = []
|
128
|
+
@doc = document
|
129
|
+
|
130
|
+
@doc.each_depth_first do |node|
|
131
|
+
@filtered_nodes.push node
|
132
|
+
instance_eval(&block)
|
133
|
+
end
|
134
|
+
|
135
|
+
puts @doc.to_JSON
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
# +current_node+ points to the node that is *now* being processed while
|
140
|
+
# running this filter.
|
141
|
+
#
|
142
|
+
# @return [Node] the node that is currently being processed
|
143
|
+
def current_node()
|
144
|
+
@filtered_nodes.last
|
145
|
+
end
|
146
|
+
|
147
|
+
# Specify what nodes to filter with a +selector+. If the +current_node+
|
148
|
+
# matches that selector, it is passed to the block to this +with+ method.
|
149
|
+
#
|
150
|
+
# @param selector [String] a selector string
|
151
|
+
# @yield [Node] the current node if it matches the selector
|
152
|
+
def with(selector)
|
153
|
+
@selectors[selector] = Selector.new selector unless @selectors.has_key? selector
|
154
|
+
yield current_node if @selectors[selector].matches? current_node, @filtered_nodes
|
155
|
+
end
|
156
|
+
|
157
|
+
# While running a filter you can access the document's metadata through
|
158
|
+
# the +metadata+ method.
|
159
|
+
#
|
160
|
+
# @return [Meta] the filtered document's metadata
|
161
|
+
def metadata()
|
162
|
+
@doc.meta
|
163
|
+
end
|
115
164
|
|
116
|
-
# Specify what nodes to filter with a +selector+. If the +current_node+
|
117
|
-
# matches that selector, it is passed to the block to this +with+ method.
|
118
|
-
|
119
|
-
def with selector
|
120
|
-
@selectors[selector] = Selector.new selector unless @selectors.has_key? selector
|
121
|
-
yield current_node if @selectors[selector].matches? current_node, @filtered_nodes
|
122
165
|
end
|
123
|
-
|
124
|
-
# While running a filter you can access the document's metadata through
|
125
|
-
# the +metadata+ method.
|
126
|
-
|
127
|
-
def metadata
|
128
|
-
@doc.meta
|
129
|
-
end
|
130
|
-
|
131
|
-
end
|
132
166
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright 2015, 2016 Huub de Beer <Huub@heerdebeer.org>
|
2
|
+
# Copyright 2015, 2016, 2017 Huub de Beer <Huub@heerdebeer.org>
|
3
3
|
#
|
4
4
|
# This file is part of Paru
|
5
5
|
#
|
@@ -17,46 +17,82 @@
|
|
17
17
|
# along with Paru. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
#++
|
19
19
|
module Paru
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
20
|
+
module PandocFilter
|
21
|
+
|
22
|
+
# ASTManipulation is a mixin for Node with some standard tree
|
23
|
+
# manipulation methods such as inserting or removing nodes, replacing
|
24
|
+
# nodes, and so on.
|
25
|
+
module ASTManipulation
|
26
|
+
|
27
|
+
# Insert child node among this node's children at position index.
|
28
|
+
#
|
29
|
+
# @param index [Integer] the position to insert the child
|
30
|
+
# @param child [Node] the child to insert
|
31
|
+
def insert(index, child)
|
32
|
+
@children.insert index, child
|
33
|
+
end
|
34
|
+
|
35
|
+
# Delete child from this node's children.
|
36
|
+
#
|
37
|
+
# @param child [Node] the child node to delete.
|
38
|
+
def delete(child)
|
39
|
+
@children.delete child
|
40
|
+
end
|
41
|
+
|
42
|
+
# Remove the child at position index from this node's children
|
43
|
+
#
|
44
|
+
# @param index [Integer] the position of the child to remove
|
45
|
+
def remove_at(index)
|
46
|
+
@children.delete_at index
|
47
|
+
end
|
50
48
|
|
51
|
-
|
52
|
-
|
53
|
-
|
49
|
+
# Append a child to the list with this node's children.
|
50
|
+
#
|
51
|
+
# @param child [Node] the child to append.
|
52
|
+
def append(child)
|
53
|
+
@children.push child
|
54
|
+
end
|
55
|
+
alias << append
|
54
56
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
# Prepend a child to the list with this node's children.
|
58
|
+
#
|
59
|
+
# @param child [Node] the child to prepend.
|
60
|
+
def prepend(child)
|
61
|
+
insert 0, child
|
62
|
+
end
|
59
63
|
|
64
|
+
# Replace a child from this node's children with a new child.
|
65
|
+
#
|
66
|
+
# @param old_child [Node] the child to replace
|
67
|
+
# @param new_child [Node] the replacement child
|
68
|
+
def replace(old_child, new_child)
|
69
|
+
old_child_index = @children.find_index old_child
|
70
|
+
if old_child_index then
|
71
|
+
replace_at old_child_index, new_child
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Replace the child at position index from this node's children
|
76
|
+
# with a new child.
|
77
|
+
#
|
78
|
+
# @param index [Integer] the position of the child to replace
|
79
|
+
# @param new_child [Node] the replacement child
|
80
|
+
def replace_at(index, new_child)
|
81
|
+
@children[index] = new_child
|
82
|
+
end
|
83
|
+
|
84
|
+
# Walk the node tree starting at this node, depth first, and apply
|
85
|
+
# block to each node in the tree
|
86
|
+
#
|
87
|
+
# @param block [Proc] the block to apply to each node in this node
|
88
|
+
# tree
|
89
|
+
#
|
90
|
+
# @yield node
|
91
|
+
def each_depth_first(&block)
|
92
|
+
yield self
|
93
|
+
each {|child| child.each_depth_first(&block)} if has_children?
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
60
97
|
end
|
61
|
-
end
|
62
98
|
end
|