paru 1.5.0 → 1.5.1
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/error.rb +6 -4
- data/lib/paru/filter/ast_manipulation.rb +90 -91
- data/lib/paru/filter/attr.rb +75 -69
- data/lib/paru/filter/block.rb +15 -14
- data/lib/paru/filter/block_quote.rb +14 -12
- data/lib/paru/filter/bullet_list.rb +17 -16
- data/lib/paru/filter/caption.rb +50 -48
- data/lib/paru/filter/cell.rb +52 -50
- data/lib/paru/filter/citation.rb +53 -51
- data/lib/paru/filter/cite.rb +34 -33
- data/lib/paru/filter/code.rb +51 -49
- data/lib/paru/filter/code_block.rb +76 -76
- data/lib/paru/filter/col_spec.rb +58 -56
- data/lib/paru/filter/definition_list.rb +51 -52
- data/lib/paru/filter/definition_list_item.rb +45 -43
- data/lib/paru/filter/div.rb +37 -35
- data/lib/paru/filter/document.rb +112 -115
- data/lib/paru/filter/emph.rb +7 -5
- data/lib/paru/filter/empty_block.rb +17 -16
- data/lib/paru/filter/empty_inline.rb +23 -22
- data/lib/paru/filter/figure.rb +41 -39
- data/lib/paru/filter/header.rb +41 -39
- data/lib/paru/filter/horizontal_rule.rb +7 -5
- data/lib/paru/filter/image.rb +13 -12
- data/lib/paru/filter/inline.rb +27 -26
- data/lib/paru/filter/inner_markdown.rb +60 -62
- data/lib/paru/filter/int_value.rb +19 -18
- data/lib/paru/filter/line_block.rb +13 -11
- data/lib/paru/filter/line_break.rb +7 -5
- data/lib/paru/filter/link.rb +34 -33
- data/lib/paru/filter/list.rb +37 -37
- data/lib/paru/filter/list_attributes.rb +52 -51
- data/lib/paru/filter/math.rb +66 -64
- data/lib/paru/filter/meta.rb +40 -39
- data/lib/paru/filter/meta_blocks.rb +7 -5
- data/lib/paru/filter/meta_bool.rb +7 -5
- data/lib/paru/filter/meta_inlines.rb +9 -7
- data/lib/paru/filter/meta_list.rb +7 -5
- data/lib/paru/filter/meta_map.rb +50 -49
- data/lib/paru/filter/meta_string.rb +7 -6
- data/lib/paru/filter/meta_value.rb +26 -25
- data/lib/paru/filter/metadata.rb +150 -88
- data/lib/paru/filter/node.rb +400 -406
- data/lib/paru/filter/note.rb +29 -29
- data/lib/paru/filter/null.rb +7 -5
- data/lib/paru/filter/ordered_list.rb +50 -49
- data/lib/paru/filter/para.rb +21 -20
- data/lib/paru/filter/plain.rb +23 -21
- data/lib/paru/filter/quoted.rb +28 -26
- data/lib/paru/filter/short_caption.rb +7 -5
- data/lib/paru/filter/small_caps.rb +8 -7
- data/lib/paru/filter/soft_break.rb +7 -5
- data/lib/paru/filter/space.rb +7 -5
- data/lib/paru/filter/span.rb +29 -27
- data/lib/paru/filter/str.rb +33 -32
- data/lib/paru/filter/strikeout.rb +7 -6
- data/lib/paru/filter/strong.rb +7 -6
- data/lib/paru/filter/subscript.rb +7 -6
- data/lib/paru/filter/superscript.rb +7 -6
- data/lib/paru/filter/table.rb +201 -210
- data/lib/paru/filter/table_body.rb +67 -67
- data/lib/paru/filter/table_end.rb +53 -55
- data/lib/paru/filter/table_foot.rb +8 -7
- data/lib/paru/filter/table_head.rb +8 -7
- data/lib/paru/filter/target.rb +29 -27
- data/lib/paru/filter/underline.rb +7 -5
- data/lib/paru/filter/value.rb +74 -75
- data/lib/paru/filter/version.rb +23 -22
- data/lib/paru/filter.rb +355 -331
- data/lib/paru/filter_error.rb +7 -5
- data/lib/paru/info.rb +29 -30
- data/lib/paru/pandoc.rb +241 -248
- data/lib/paru/pandoc2yaml.rb +51 -42
- data/lib/paru/selector.rb +193 -184
- data/lib/paru.rb +3 -1
- metadata +4 -73
data/lib/paru/filter_error.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#--
|
2
|
-
# Copyright 2015
|
4
|
+
# Copyright 2015--2025 Huub de Beer <Huub@heerdebeer.org>
|
3
5
|
#
|
4
6
|
# This file is part of Paru
|
5
7
|
#
|
@@ -16,10 +18,10 @@
|
|
16
18
|
# You should have received a copy of the GNU General Public License
|
17
19
|
# along with Paru. If not, see <http://www.gnu.org/licenses/>.
|
18
20
|
#++
|
19
|
-
require_relative
|
21
|
+
require_relative 'error'
|
20
22
|
|
21
23
|
module Paru
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
# A FilterError raised when there is an error while running a filter.
|
25
|
+
class FilterError < Error
|
26
|
+
end
|
25
27
|
end
|
data/lib/paru/info.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright 2022 Huub de Beer <Huub@heerdebeer.org>
|
2
|
+
# Copyright 2022-2025 Huub de Beer <Huub@heerdebeer.org>
|
3
3
|
#
|
4
4
|
# This file is part of Paru
|
5
5
|
#
|
@@ -18,7 +18,8 @@
|
|
18
18
|
#++
|
19
19
|
|
20
20
|
# frozen_string_literal: false
|
21
|
-
|
21
|
+
|
22
|
+
require_relative 'error'
|
22
23
|
|
23
24
|
module Paru
|
24
25
|
# Information about pandoc
|
@@ -38,51 +39,49 @@ module Paru
|
|
38
39
|
#
|
39
40
|
# @param path [String] the path to pandoc. Defaults to 'pandoc', i.e.,
|
40
41
|
# assumes it's on the environment's path.
|
41
|
-
def initialize(path =
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
42
|
+
def initialize(path = 'pandoc')
|
43
|
+
# Get pandoc's version information
|
44
|
+
version_string = ''
|
45
|
+
IO.popen("#{path} --version", 'r+') do |p|
|
46
|
+
p.close_write
|
47
|
+
version_string << p.read
|
48
|
+
end
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
# Extract the version as an array of integers, like SemVer.
|
51
|
+
@version = version_string
|
52
|
+
.match(/pandoc.* (\d+\.\d+.*)$/)[1]
|
53
|
+
.split('.')
|
54
|
+
.map(&:to_i)
|
55
55
|
|
56
|
-
|
57
|
-
|
56
|
+
# Extract the data directory
|
57
|
+
@data_dir = version_string.match(/User data directory: (.+)$/)[1]
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
# Extract scripting engine
|
60
|
+
@scripting_engine = version_string.match(/Scripting engine: (.+)$/)[1]
|
61
|
+
rescue StandardError => e
|
62
|
+
warn "Error extracting pandoc's information: #{e.message}"
|
63
|
+
warn 'Using made up values instead.'
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
65
|
+
@version ||= [2, 18]
|
66
|
+
@data_dir ||= '.'
|
67
|
+
@scripting_engine ||= 'Lua 5.4'
|
69
68
|
end
|
70
69
|
|
71
70
|
# Get pandoc's info by key like a Hash for backwards compatability.
|
72
71
|
#
|
73
72
|
# @deprecated Use Info's getters instead.
|
74
|
-
#
|
73
|
+
#
|
75
74
|
# @param key [String|Symbol] the key for the information to look up.
|
76
75
|
# Info only supports keys 'version' and 'data_dir'.
|
77
76
|
# @return [Any] Information associated with the key.
|
78
77
|
# @raise [Error] for an unknown key.
|
79
78
|
def [](key)
|
80
79
|
case key
|
81
|
-
when
|
80
|
+
when 'verion', :version
|
82
81
|
version
|
83
|
-
when
|
82
|
+
when 'data_dir', :data_dir
|
84
83
|
data_dir
|
85
|
-
when
|
84
|
+
when 'scripting_engine', :scripting_engine
|
86
85
|
scripting_engine
|
87
86
|
else
|
88
87
|
throw Error.new "Info does not know key '#{key}'"
|
data/lib/paru/pandoc.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright 2015
|
2
|
+
# Copyright 2015--2025 Huub de Beer <Huub@heerdebeer.org>
|
3
3
|
#
|
4
4
|
# This file is part of Paru
|
5
5
|
#
|
@@ -18,286 +18,279 @@
|
|
18
18
|
#++
|
19
19
|
|
20
20
|
# frozen_string_literal: false
|
21
|
-
require "open3"
|
22
|
-
require "shellwords"
|
23
|
-
require "yaml"
|
24
21
|
|
25
|
-
|
26
|
-
|
22
|
+
require 'open3'
|
23
|
+
require 'shellwords'
|
24
|
+
require 'yaml'
|
25
|
+
|
26
|
+
require_relative 'error'
|
27
|
+
require_relative 'info'
|
27
28
|
|
28
29
|
module Paru
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
# Pandoc is a wrapper around the pandoc document converter. See
|
31
|
+
# <http://pandoc.org/README.html> for details about pandoc. The Pandoc
|
32
|
+
# class is basically a straightforward translation from the pandoc command
|
33
|
+
# line program to Ruby. It is a Rubyesque API to work with pandoc.
|
34
|
+
#
|
35
|
+
# For information about writing pandoc filters in Ruby see {Filter}.
|
36
|
+
#
|
37
|
+
# Creating a Paru pandoc converter in Ruby is quite straightforward: you
|
38
|
+
# create a new Paru::Pandoc object with a block that configures that
|
39
|
+
# Pandoc object with pandoc options. Each command-line option to pandoc is
|
40
|
+
# a method on the Pandoc object. Command-line options with dashes in them,
|
41
|
+
# such as "--reference-docx", can be called by replacing the dash with an
|
42
|
+
# underscore. So, "--reference-docx" becomes the method +reference_docx+.
|
43
|
+
#
|
44
|
+
# Pandoc command-line flags, such as "--parse-raw", "--chapters", or
|
45
|
+
# "--toc", have been translated to Paru::Pandoc methods that take an
|
46
|
+
# optional Boolean parameter; +true+ is the default value. Therefore, if
|
47
|
+
# you want to enable a flag, no parameter is needed.
|
48
|
+
#
|
49
|
+
# All other pandoc command-line options are translated to Paru::Pandoc
|
50
|
+
# methods that take either one String or Number argument, or a list of
|
51
|
+
# String arguments if that command-line option can occur more than once
|
52
|
+
# (such as "--include-before-header" or "--filter").
|
53
|
+
#
|
54
|
+
# Once you have configured a Paru::Pandoc converter, you can call
|
55
|
+
# +convert+ or +<<+ (which is an alias for +convert+) with a string to
|
56
|
+
# convert. You can call +convert+ as often as you like and, if you like,
|
57
|
+
# reconfigure the converter in between!
|
58
|
+
#
|
59
|
+
#
|
60
|
+
# @example Convert the markdown string 'hello *world*' to HTML
|
61
|
+
# Paru::Pandoc.new do
|
62
|
+
# from 'markdown
|
63
|
+
# to 'html'
|
64
|
+
# end << 'hello *world*'
|
65
|
+
#
|
66
|
+
# @example Convert a HTML file to DOCX with a reference file
|
67
|
+
# Paru::Pandoc.new do
|
68
|
+
# from "html"
|
69
|
+
# to "docx"
|
70
|
+
# reference_docx "styled_output.docx"
|
71
|
+
# output "output.docx"
|
72
|
+
# end.convert File.read("input.html")
|
73
|
+
#
|
74
|
+
# @example Convert a markdown file to html but add in references in APA style
|
75
|
+
# Paru::Pandoc.new do
|
76
|
+
# from "markdown"
|
77
|
+
# toc
|
78
|
+
# bibliography "literature.bib"
|
79
|
+
# to "html"
|
80
|
+
# csl "apa.csl"
|
81
|
+
# output "report_with_references.md"
|
82
|
+
# end << File.read("report.md")
|
83
|
+
#
|
84
|
+
#
|
85
|
+
class Pandoc
|
86
|
+
# Use a readable option separator on Unix-like systems, but fall back
|
87
|
+
# to a space on Windows.
|
88
|
+
DEFAULT_OPTION_SEP = Gem.win_platform? ? ' ' : " \\\n\t"
|
89
|
+
|
90
|
+
# Path to the pandoc executatble to use by paru.
|
91
|
+
PARU_PANDOC_PATH = 'PARU_PANDOC_PATH'.freeze
|
92
|
+
|
93
|
+
# Gather information about the pandoc installation. It runs +pandoc
|
94
|
+
# --version+ and extracts pandoc's version number and default data
|
95
|
+
# directory. This method is typically used in scripts that use Paru to
|
96
|
+
# automate the use of pandoc.
|
33
97
|
#
|
34
|
-
#
|
98
|
+
# @return [Info] Pandoc's version, such as "[2.10.1]" and the data directory, such as "/home/huub/.pandoc".
|
99
|
+
def self.info
|
100
|
+
@@info
|
101
|
+
end
|
102
|
+
|
103
|
+
# Create a new Pandoc converter, optionally configured by a block with
|
104
|
+
# pandoc options. See {#configure} on how to configure a converter.
|
35
105
|
#
|
36
|
-
#
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
106
|
+
# @param block [Proc] an optional configuration block.
|
107
|
+
def initialize(&block)
|
108
|
+
@options = {}
|
109
|
+
configure(&block) if block_given?
|
110
|
+
end
|
111
|
+
|
112
|
+
# Configure this Pandoc converter with block. In the block you can
|
113
|
+
# call all pandoc options as methods on this converter. In multi-word
|
114
|
+
# options the dash (-) is replaced by an underscore (_)
|
42
115
|
#
|
43
|
-
# Pandoc command
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
116
|
+
# Pandoc has a number of command line options. Most are simple options,
|
117
|
+
# like flags, that can be set only once. Other options can occur more than
|
118
|
+
# once, such as the css option: to add more than one css file to a
|
119
|
+
# generated standalone html file, use the css options once for each
|
120
|
+
# stylesheet to include. Other options do have the pattern key[:value],
|
121
|
+
# which can also occur multiple times, such as metadata.
|
47
122
|
#
|
48
|
-
# All
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
123
|
+
# All options are specified in a pandoc_options.yaml. If it is an option
|
124
|
+
# that can occur only once, the value of the option in that yaml file is
|
125
|
+
# its default value. If the option can occur multiple times, its value is
|
126
|
+
# an array with one value, the default value.
|
52
127
|
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
# convert. You can call +convert+ as often as you like and, if you like,
|
56
|
-
# reconfigure the converter in between!
|
128
|
+
# @param block [Proc] the options to pandoc
|
129
|
+
# @return [Pandoc] this Pandoc converter
|
57
130
|
#
|
131
|
+
# @example Configure converting HTML to LaTeX with a LaTeX engine
|
132
|
+
# converter.configure do
|
133
|
+
# from 'html'
|
134
|
+
# to 'latex'
|
135
|
+
# latex_engine 'lualatex'
|
136
|
+
# end
|
58
137
|
#
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
138
|
+
def configure(&block)
|
139
|
+
instance_eval(&block)
|
140
|
+
self
|
141
|
+
end
|
142
|
+
|
143
|
+
# Converts input string to output string using the pandoc invocation
|
144
|
+
# configured in this Pandoc instance.
|
64
145
|
#
|
65
|
-
# @
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
# reference_docx "styled_output.docx"
|
70
|
-
# output "output.docx"
|
71
|
-
# end.convert File.read("input.html")
|
146
|
+
# @param input [String] the input string to convert
|
147
|
+
# @return [String] the converted output as a string. Note. For some
|
148
|
+
# formats, output to STDOUT is not supported (see pandoc's manual) and
|
149
|
+
# the result string will be empty.
|
72
150
|
#
|
73
|
-
#
|
74
|
-
# Paru::Pandoc.new do
|
75
|
-
# from "markdown"
|
76
|
-
# toc
|
77
|
-
# bibliography "literature.bib"
|
78
|
-
# to "html"
|
79
|
-
# csl "apa.csl"
|
80
|
-
# output "report_with_references.md"
|
81
|
-
# end << File.read("report.md")
|
151
|
+
# The following two examples are the same:
|
82
152
|
#
|
153
|
+
# @example Using convert
|
154
|
+
# output = converter.convert 'this is a *strong* word'
|
83
155
|
#
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
# Path to the pandoc executatble to use by paru.
|
91
|
-
PARU_PANDOC_PATH = "PARU_PANDOC_PATH"
|
92
|
-
|
93
|
-
# Gather information about the pandoc installation. It runs +pandoc
|
94
|
-
# --version+ and extracts pandoc's version number and default data
|
95
|
-
# directory. This method is typically used in scripts that use Paru to
|
96
|
-
# automate the use of pandoc.
|
97
|
-
#
|
98
|
-
# @return [Info] Pandoc's version, such as "[2.10.1]" and the data directory, such as "/home/huub/.pandoc".
|
99
|
-
def self.info()
|
100
|
-
@@info
|
101
|
-
end
|
102
|
-
|
103
|
-
# Create a new Pandoc converter, optionally configured by a block with
|
104
|
-
# pandoc options. See {#configure} on how to configure a converter.
|
105
|
-
#
|
106
|
-
# @param block [Proc] an optional configuration block.
|
107
|
-
def initialize(&block)
|
108
|
-
@options = {}
|
109
|
-
configure(&block) if block_given?
|
110
|
-
end
|
111
|
-
|
112
|
-
# Configure this Pandoc converter with block. In the block you can
|
113
|
-
# call all pandoc options as methods on this converter. In multi-word
|
114
|
-
# options the dash (-) is replaced by an underscore (_)
|
115
|
-
#
|
116
|
-
# Pandoc has a number of command line options. Most are simple options,
|
117
|
-
# like flags, that can be set only once. Other options can occur more than
|
118
|
-
# once, such as the css option: to add more than one css file to a
|
119
|
-
# generated standalone html file, use the css options once for each
|
120
|
-
# stylesheet to include. Other options do have the pattern key[:value],
|
121
|
-
# which can also occur multiple times, such as metadata.
|
122
|
-
#
|
123
|
-
# All options are specified in a pandoc_options.yaml. If it is an option
|
124
|
-
# that can occur only once, the value of the option in that yaml file is
|
125
|
-
# its default value. If the option can occur multiple times, its value is
|
126
|
-
# an array with one value, the default value.
|
127
|
-
#
|
128
|
-
# @param block [Proc] the options to pandoc
|
129
|
-
# @return [Pandoc] this Pandoc converter
|
130
|
-
#
|
131
|
-
# @example Configure converting HTML to LaTeX with a LaTeX engine
|
132
|
-
# converter.configure do
|
133
|
-
# from 'html'
|
134
|
-
# to 'latex'
|
135
|
-
# latex_engine 'lualatex'
|
136
|
-
# end
|
137
|
-
#
|
138
|
-
def configure(&block)
|
139
|
-
instance_eval(&block)
|
140
|
-
self
|
141
|
-
end
|
156
|
+
# @example Using <<
|
157
|
+
# output = converter << 'this is a *strong* word'
|
158
|
+
def convert(input)
|
159
|
+
run_converter to_command, input
|
160
|
+
end
|
161
|
+
alias << convert
|
142
162
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
# output = converter << 'this is a *strong* word'
|
158
|
-
def convert(input)
|
159
|
-
run_converter to_command, input
|
160
|
-
end
|
161
|
-
alias << convert
|
162
|
-
|
163
|
-
# Converts an input file to output string using the pandoc invocation
|
164
|
-
# configured in this Pandoc instance. The path to the input file is
|
165
|
-
# appended to that invocation.
|
166
|
-
#
|
167
|
-
# @param input_file [String] the path to the input file to convert
|
168
|
-
# @return [String] the converted output as a string. Note. For some
|
169
|
-
# formats, output to STDOUT is not supported (see pandoc's manual) and
|
170
|
-
# the result string will be empty.
|
171
|
-
#
|
172
|
-
# @example Using convert_file
|
173
|
-
# output = converter.convert_file 'files/document.md'
|
174
|
-
def convert_file(input_file)
|
175
|
-
run_converter "#{to_command} #{input_file}"
|
176
|
-
end
|
163
|
+
# Converts an input file to output string using the pandoc invocation
|
164
|
+
# configured in this Pandoc instance. The path to the input file is
|
165
|
+
# appended to that invocation.
|
166
|
+
#
|
167
|
+
# @param input_file [String] the path to the input file to convert
|
168
|
+
# @return [String] the converted output as a string. Note. For some
|
169
|
+
# formats, output to STDOUT is not supported (see pandoc's manual) and
|
170
|
+
# the result string will be empty.
|
171
|
+
#
|
172
|
+
# @example Using convert_file
|
173
|
+
# output = converter.convert_file 'files/document.md'
|
174
|
+
def convert_file(input_file)
|
175
|
+
run_converter "#{to_command} #{input_file}"
|
176
|
+
end
|
177
177
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
178
|
+
# Create a string representation of this converter's pandoc command
|
179
|
+
# line invocation. This is useful for debugging purposes.
|
180
|
+
#
|
181
|
+
# @param option_sep [String] the string to separate options with
|
182
|
+
# @return [String] This converter's command line invocation string.
|
183
|
+
def to_command(option_sep = DEFAULT_OPTION_SEP)
|
184
|
+
"#{escape(@@pandoc_exec)}\t#{to_option_string option_sep}"
|
185
|
+
end
|
186
186
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
end
|
210
|
-
end
|
211
|
-
options_arr.join(option_sep)
|
187
|
+
private
|
188
|
+
|
189
|
+
def to_option_string(option_sep)
|
190
|
+
options_arr = []
|
191
|
+
@options.each do |option, value|
|
192
|
+
option_string = "--#{option.to_s.gsub '_', '-'}"
|
193
|
+
|
194
|
+
case value
|
195
|
+
when TrueClass
|
196
|
+
# Flags don't have a value, only its name
|
197
|
+
# For example: --standalone
|
198
|
+
options_arr.push option_string.to_s
|
199
|
+
when FalseClass
|
200
|
+
# Skip this option; consider a flag with value false as unset
|
201
|
+
when Array
|
202
|
+
# This option can occur multiple times: list each with its value.
|
203
|
+
# For example: --css=main.css --css=print.css
|
204
|
+
options_arr.push value.map { |val| "#{option_string}=#{escape(val.to_s)}" }.join(option_sep)
|
205
|
+
else
|
206
|
+
# All options that aren't flags and can occur only once have the
|
207
|
+
# same pattern: --option=value
|
208
|
+
options_arr.push "#{option_string}=#{escape(value.to_s)}"
|
212
209
|
end
|
210
|
+
end
|
211
|
+
options_arr.join(option_sep)
|
212
|
+
end
|
213
213
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
214
|
+
# determine pandoc_executable to use in paru
|
215
|
+
@@pandoc_exec = if ENV.key? PARU_PANDOC_PATH
|
216
|
+
ENV[PARU_PANDOC_PATH]
|
217
|
+
else
|
218
|
+
'pandoc'
|
219
|
+
end
|
220
220
|
|
221
|
-
|
221
|
+
@@info = Info.new(@@pandoc_exec)
|
222
222
|
|
223
|
-
|
224
|
-
|
223
|
+
# For each pandoc command line option a method is defined as follows:
|
224
|
+
OPTIONS = YAML.load_file File.join(__dir__, 'pandoc_options.yaml')
|
225
225
|
|
226
|
-
|
227
|
-
|
226
|
+
OPTIONS.each_pair do |option, default|
|
227
|
+
if OPTIONS[option].is_a? Array
|
228
228
|
|
229
|
-
|
230
|
-
|
229
|
+
# option can be set multiple times, for example adding multiple css
|
230
|
+
# files
|
231
231
|
|
232
|
-
|
233
|
-
|
232
|
+
define_method(option) do |value = default|
|
233
|
+
value = [] if value.nil?
|
234
234
|
|
235
|
-
|
236
|
-
@options[option] = []
|
237
|
-
end
|
235
|
+
@options[option] = [] if @options[option].nil?
|
238
236
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
self
|
246
|
-
end
|
237
|
+
if value.is_a? Array
|
238
|
+
@options[option] += value
|
239
|
+
else
|
240
|
+
@options[option].push value
|
241
|
+
end
|
247
242
|
|
248
|
-
|
249
|
-
|
243
|
+
self
|
244
|
+
end
|
250
245
|
|
251
|
-
|
252
|
-
|
253
|
-
value = default if value.nil?
|
246
|
+
else
|
247
|
+
# option can be set only once, for example a flag or a template
|
254
248
|
|
255
|
-
|
256
|
-
|
257
|
-
|
249
|
+
default = OPTIONS[option]
|
250
|
+
define_method(option) do |value = default|
|
251
|
+
value = default if value.nil?
|
258
252
|
|
259
|
-
|
253
|
+
@options[option] = value
|
254
|
+
self
|
260
255
|
end
|
261
256
|
|
262
|
-
|
263
|
-
|
264
|
-
def escape(str)
|
265
|
-
if Gem.win_platform?
|
266
|
-
escaped = str.gsub("\\", "\\\\")
|
267
|
-
"\"#{escaped}\""
|
268
|
-
else
|
269
|
-
str.shellescape
|
270
|
-
end
|
271
|
-
end
|
257
|
+
end
|
258
|
+
end
|
272
259
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
stdin << input unless input.nil?
|
281
|
-
stdin.close
|
282
|
-
output << stdout.read
|
283
|
-
error << stderr.read
|
284
|
-
status = thread.value.exitstatus
|
285
|
-
end
|
286
|
-
|
287
|
-
warn error unless error.empty?
|
288
|
-
|
289
|
-
if 0 < status
|
290
|
-
# pandoc exited with an error
|
291
|
-
raise Paru::Error.new "error while running:\n\n#{command}\n\nPandoc responded with:\n\n#{error}\n"
|
292
|
-
end
|
293
|
-
|
294
|
-
output
|
295
|
-
rescue Paru::Error => err
|
296
|
-
raise err
|
297
|
-
rescue StandardError => err
|
298
|
-
throw Error.new "Unable to run pandoc via command '#{command}': #{err.message}"
|
299
|
-
end
|
300
|
-
end
|
260
|
+
def escape(str)
|
261
|
+
if Gem.win_platform?
|
262
|
+
escaped = str.gsub('\\', '\\\\')
|
263
|
+
"\"#{escaped}\""
|
264
|
+
else
|
265
|
+
str.shellescape
|
266
|
+
end
|
301
267
|
end
|
302
268
|
|
269
|
+
def run_converter(command, input = nil)
|
270
|
+
output = ''
|
271
|
+
error = ''
|
272
|
+
status = 0
|
273
|
+
|
274
|
+
Open3.popen3(command) do |stdin, stdout, stderr, thread|
|
275
|
+
stdin << input unless input.nil?
|
276
|
+
stdin.close
|
277
|
+
output << stdout.read
|
278
|
+
error << stderr.read
|
279
|
+
status = thread.value.exitstatus
|
280
|
+
end
|
281
|
+
|
282
|
+
warn error unless error.empty?
|
283
|
+
|
284
|
+
if status.positive?
|
285
|
+
# pandoc exited with an error
|
286
|
+
raise Paru::Error, "error while running:\n\n#{command}\n\nPandoc responded with:\n\n#{error}\n"
|
287
|
+
end
|
288
|
+
|
289
|
+
output
|
290
|
+
rescue Paru::Error => e
|
291
|
+
raise e
|
292
|
+
rescue StandardError => e
|
293
|
+
throw Error.new "Unable to run pandoc via command '#{command}': #{e.message}"
|
294
|
+
end
|
295
|
+
end
|
303
296
|
end
|