pandoc-ruby 1.0.0 → 2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bb86a51dc3901cc03725daebcaa9afe2c4d2d4b2
4
- data.tar.gz: 0c53e1b182af84515130b764a06d68041dae22ab
3
+ metadata.gz: 606934acc12140a2ce1f99e2f9c4e0cadfc24977
4
+ data.tar.gz: 6ae5fa55a9d05bb7f9f915d45a388f06869395fe
5
5
  SHA512:
6
- metadata.gz: d607cd66c09554e971bd9757e2b155125867117d5ce4a6dcac8f08e8245f9261a40b1b6843cc52dae87afe26da885f04f7f338b19891a2b637cb529ce4781ff8
7
- data.tar.gz: eaa4f5abf913287d78d70f054e64e0bde58d7c3675151ac058850bfa87ee9e77c5857cf649aace0fac640c3f001ad37d0ffa5b000199617592d0788a1adbc434
6
+ metadata.gz: 367018a0d5f56c3edac2a521ade4c695b6afc14f1755dc11605f30856a71b1ed7160da1aead1a4aa0e9919175a6e40e920bb0908bfb90539e98c3a397744e062
7
+ data.tar.gz: 9ebe803a32985af625b33165cf5db03d9daca6763bda2a80dda948e41fcd58bfdb46eac2181a8a0da2ba21a711ad3747cafce25d2cf80ac9fe76fad2c2d52b4e
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "http://rubygems.org"
1
+ source 'http://rubygems.org'
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
@@ -6,9 +6,8 @@ source "http://rubygems.org"
6
6
  # Add dependencies to develop your gem here.
7
7
  # Include everything needed to run rake, tests, features, etc.
8
8
  group :development, :test do
9
- gem "mocha", "~> 1.1.0"
10
- gem "rake"
11
- gem "rdoc", "~> 4.2.0"
12
- gem "shoulda", "~> 3.5.0"
13
- gem "test-unit", "~> 3.0.9"
9
+ gem 'minitest', '~>5.8.3'
10
+ gem 'mocha', '~>1.1.0'
11
+ gem 'rake'
12
+ gem 'rdoc'
14
13
  end
@@ -1,39 +1,21 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- activesupport (4.2.0)
5
- i18n (~> 0.7)
6
- json (~> 1.7, >= 1.7.7)
7
- minitest (~> 5.1)
8
- thread_safe (~> 0.3, >= 0.3.4)
9
- tzinfo (~> 1.1)
10
- i18n (0.7.0)
11
- json (1.8.2)
12
4
  metaclass (0.0.4)
13
- minitest (5.5.1)
5
+ minitest (5.8.3)
14
6
  mocha (1.1.0)
15
7
  metaclass (~> 0.0.1)
16
- power_assert (0.2.2)
17
8
  rake (10.4.2)
18
9
  rdoc (4.2.0)
19
- shoulda (3.5.0)
20
- shoulda-context (~> 1.0, >= 1.0.1)
21
- shoulda-matchers (>= 1.4.1, < 3.0)
22
- shoulda-context (1.2.1)
23
- shoulda-matchers (2.8.0)
24
- activesupport (>= 3.0.0)
25
- test-unit (3.0.9)
26
- power_assert
27
- thread_safe (0.3.4)
28
- tzinfo (1.2.2)
29
- thread_safe (~> 0.1)
30
10
 
31
11
  PLATFORMS
32
12
  ruby
33
13
 
34
14
  DEPENDENCIES
15
+ minitest (~> 5.8.3)
35
16
  mocha (~> 1.1.0)
36
17
  rake
37
- rdoc (~> 4.2.0)
38
- shoulda (~> 3.5.0)
39
- test-unit (~> 3.0.9)
18
+ rdoc
19
+
20
+ BUNDLED WITH
21
+ 1.10.6
@@ -0,0 +1,131 @@
1
+ # PandocRuby
2
+
3
+ PandocRuby is a wrapper for [Pandoc](http://johnmacfarlane.net/pandoc/), a
4
+ Haskell library with command line tools for converting one markup format to
5
+ another.
6
+
7
+ Pandoc can convert documents in markdown, reStructuredText, textile, HTML,
8
+ DocBook, LaTeX, or MediaWiki markup to a variety of formats, including
9
+ markdown, reStructuredText, HTML, LaTeX, ConTeXt, PDF, RTF, DocBook XML,
10
+ OpenDocument XML, ODT, GNU Texinfo, MediaWiki markup, groff man pages,
11
+ HTML slide shows, EPUB, and Microsoft Word docx.
12
+
13
+ *This documentation is for version 2 and higher. For version 1 documentation
14
+ [see here](https://github.com/alphabetum/pandoc-ruby/blob/v1.0.0/README.markdown).*
15
+
16
+ ## Installation
17
+
18
+ First, make sure to
19
+ [install Pandoc](http://johnmacfarlane.net/pandoc/installing.html).
20
+
21
+ Next, add PandocRuby to your Gemfile
22
+
23
+ ```ruby
24
+ gem 'pandoc-ruby'
25
+ ```
26
+
27
+ or install PandocRuby from [RubyGems](http://rubygems.org/gems/pandoc-ruby).
28
+
29
+ ```bash
30
+ gem install pandoc-ruby
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ```ruby
36
+ require 'pandoc-ruby'
37
+ @converter = PandocRuby.new('# Markdown Title', :from => :markdown, :to => :rst)
38
+ puts @converter.convert
39
+ ```
40
+
41
+ This takes the Markdown formatted file and converts it to reStructuredText.
42
+
43
+ You can also use the `#convert` class method:
44
+
45
+ ```ruby
46
+ puts PandocRuby.convert('# Markdown Title', :from => :markdown, :to => :html)
47
+ ```
48
+
49
+ Other arguments are simply converted into command line options, accepting
50
+ symbols or strings for options without arguments and hashes of strings or
51
+ symbols for options with arguments.
52
+
53
+ ```ruby
54
+ PandocRuby.convert('# Markdown Title', :s, {:f => :markdown, :to => :rst}, 'no-wrap', :table_of_contents)
55
+ ```
56
+
57
+ is equivalent to
58
+
59
+ ```bash
60
+ echo "# Markdown Title" | pandoc -s -f markdown --to=rst --no-wrap --table-of-contents
61
+ ```
62
+
63
+ Also provided are `#to_[writer]` instance methods for each of the writers,
64
+ and these can also accept options:
65
+
66
+ ```ruby
67
+ PandocRuby.new("# Some title").to_html(:no_wrap)
68
+ # => "<div id=\"some-title\"><h1>Some title</h1></div>"
69
+ # or
70
+ PandocRuby.new("# Some title").to_rst
71
+ # => "Some title\n=========="
72
+ ```
73
+
74
+ Similarly, there are class methods for each of the readers, so readers
75
+ and writers can be specified like this:
76
+
77
+ ```ruby
78
+ PandocRuby.html("<h1>hello</h1>").to_latex
79
+ # => "\\section{hello}"
80
+ ```
81
+
82
+ PandocRuby assumes the `pandoc` executable is via your environment's `$PATH`
83
+ variable. If you'd like to set an explicit path to the `pandoc` executable,
84
+ you can do so with `PandocRuby.pandoc_path = '/path/to/pandoc'`
85
+
86
+ Pandoc can also be set to take an array of file paths as the first argument.
87
+
88
+ ```ruby
89
+ # One file path as a single-element array.
90
+ PandocRuby.html(['/path/to/file1.html']).to_markdown
91
+ # Multiple file paths as an array.
92
+ PandocRuby.html(['/path/to/file1.html', '/path/to/file2.html']).to_markdown
93
+ ```
94
+
95
+ Available format readers and writers are available in the `PandocRuby::READERS`
96
+ and `PandocRuby::WRITERS` constants.
97
+
98
+ For more information on Pandoc, see the
99
+ [Pandoc documentation](http://johnmacfarlane.net/pandoc/)
100
+ or run `man pandoc`
101
+ ([also available here](http://johnmacfarlane.net/pandoc/pandoc.1.html)).
102
+
103
+ If you'd prefer a pure-Ruby extended markdown interpreter that can output a
104
+ few different formats, take a look at [Maruku](http://maruku.rubyforge.org/).
105
+ If you want to use the full reStructuredText syntax from within Ruby, check
106
+ out [RbST](https://github.com/alphabetum/rbst), a docutils wrapper.
107
+
108
+ This gem was inspired by [Albino](http://github.com/github/albino). For a
109
+ slightly different approach to using Pandoc with Ruby, see
110
+ [Pandoku](http://github.com/dahlia/pandoku).
111
+
112
+ ## Additional Notes
113
+
114
+ If you are trying to generate a standalone file with full file headers rather
115
+ than just a marked up fragment, remember to pass the `:standalone` option so
116
+ the correct header and footer are added.
117
+
118
+ ```ruby
119
+ PandocRuby.new("# Some title", :standalone).to_rtf
120
+ ```
121
+
122
+ ## Note on Patches/Pull Requests
123
+
124
+ * Fork the project.
125
+ * Make your feature addition or bug fix.
126
+ * Add tests for it. This is important so I don't break it in a
127
+ future version unintentionally.
128
+ * Commit, do not mess with rakefile, version, or history.
129
+ (if you want to have your own version, that is fine but
130
+ bump version in a commit by itself I can ignore when I pull)
131
+ * Send me a pull request. Bonus points for topic branches.
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ begin
6
6
  Bundler.setup(:default, :development)
7
7
  rescue Bundler::BundlerError => e
8
8
  $stderr.puts e.message
9
- $stderr.puts "Run `bundle install` to install missing gems"
9
+ $stderr.puts 'Run `bundle install` to install missing gems'
10
10
  exit e.status_code
11
11
  end
12
12
  require 'rake'
@@ -22,7 +22,7 @@ task :default => :test
22
22
 
23
23
  require 'rdoc/task'
24
24
  Rake::RDocTask.new do |rdoc|
25
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
25
+ version = File.exist?('VERSION') ? File.read('VERSION') : ''
26
26
 
27
27
  rdoc.rdoc_dir = 'rdoc'
28
28
  rdoc.title = "pandoc-ruby #{version}"
@@ -1,18 +1,10 @@
1
1
  require 'open3'
2
2
  require 'tempfile'
3
+ require 'timeout'
3
4
 
4
5
  class PandocRuby
5
6
 
6
- @@bin_path = nil
7
- @@allow_file_paths = false
8
-
9
- # The executable options. The `pandoc` executable is used by default.
10
- EXECUTABLES = %W[
11
- pandoc
12
- markdown2pdf
13
- html2markdown
14
- hsmarkdown
15
- ]
7
+ @@pandoc_path = 'pandoc'
16
8
 
17
9
  # The available readers and their corresponding names. The keys are used to
18
10
  # generate methods and specify options to Pandoc.
@@ -23,8 +15,8 @@ class PandocRuby
23
15
  'rst' => 'reStructuredText',
24
16
  'textile' => 'textile',
25
17
  'html' => 'HTML',
26
- 'latex' => 'LaTeX',
27
- }
18
+ 'latex' => 'LaTeX'
19
+ }.freeze
28
20
 
29
21
  # The available string writers and their corresponding names. The keys are
30
22
  # used to generate methods and specify options to Pandoc.
@@ -51,7 +43,7 @@ class PandocRuby
51
43
  'rtf' => 'rich text format',
52
44
  'org' => 'emacs org mode',
53
45
  'asciidoc' => 'asciidoc'
54
- }
46
+ }.freeze
55
47
 
56
48
  # The available binary writers and their corresponding names. The keys are
57
49
  # used to generate methods and specify options to Pandoc.
@@ -60,22 +52,15 @@ class PandocRuby
60
52
  'docx' => 'Word docx',
61
53
  'epub' => 'EPUB V2',
62
54
  'epub3' => 'EPUB V3'
63
- }
55
+ }.freeze
64
56
 
65
57
  # All of the available Writers.
66
58
  WRITERS = STRING_WRITERS.merge(BINARY_WRITERS)
67
59
 
68
- # If the pandoc executables are not in the PATH, bin_path can be set to
69
- # the directory they are contained in.
70
- def self.bin_path=(path)
71
- @@bin_path = path
72
- end
73
-
74
- # Pandoc can also be used with a file path as the first argument. For
75
- # security reasons, this is disabled by default, but it can be enabled by
76
- # setting this to `true`.
77
- def self.allow_file_paths=(value)
78
- @@allow_file_paths = value
60
+ # To use run the pandoc command with a custom executable path, the path
61
+ # to the pandoc executable can be set here.
62
+ def self.pandoc_path=(path)
63
+ @@pandoc_path = path
79
64
  end
80
65
 
81
66
  # A shortcut method that creates a new PandocRuby object and immediately
@@ -87,31 +72,40 @@ class PandocRuby
87
72
  end
88
73
 
89
74
  attr_accessor :options
90
- def options; @options || [] end
75
+ def options
76
+ @options || []
77
+ end
91
78
 
92
79
  attr_accessor :option_string
93
- def option_string; @option_string || '' end
80
+ def option_string
81
+ @option_string || ''
82
+ end
94
83
 
95
84
  attr_accessor :binary_output
96
- def binary_output; @binary_output || false end
85
+ def binary_output
86
+ @binary_output || false
87
+ end
97
88
 
98
89
  attr_accessor :writer
99
- def writer; @writer || 'html' end
90
+ def writer
91
+ @writer || 'html'
92
+ end
100
93
 
101
- # Create a new PandocRuby converter object. The first argument should be
102
- # the string that will be converted or, if `.allow_file_paths` has been set
103
- # to `true`, this can also be a path to a file. The executable name can
104
- # be used as the second argument, but will default to `pandoc` if the second
105
- # argument is omitted or anything other than an executable name. Any other
106
- # arguments will be converted to pandoc options.
94
+ # Create a new PandocRuby converter object. The first argument contains the
95
+ # input either as string or as an array of filenames.
96
+ #
97
+ # Any other arguments will be converted to pandoc options.
98
+ #
99
+ # Usage:
100
+ # new("# A String", :option1 => :value, :option2)
101
+ # new(["/path/to/file.md"], :option1 => :value, :option2)
102
+ # new(["/to/file1.html", "/to/file2.html"], :option1 => :value)
107
103
  def initialize(*args)
108
- target = args.shift
109
- @target = if @@allow_file_paths && File.exists?(target)
110
- File.read(target)
111
- else
112
- target rescue target
104
+ if args[0].is_a?(String)
105
+ @input_string = args.shift
106
+ elsif args[0].is_a?(Array)
107
+ @input_files = args.shift.join(' ')
113
108
  end
114
- @executable = args.shift if EXECUTABLES.include?(args[0])
115
109
  self.options = args
116
110
  end
117
111
 
@@ -135,7 +129,7 @@ class PandocRuby
135
129
  convert_string
136
130
  end
137
131
  end
138
- alias_method :to_s, :convert
132
+ alias to_s convert
139
133
 
140
134
  # Generate class methods for each of the readers in PandocRuby::READERS.
141
135
  # When one of these methods is called, it simply calls the initializer
@@ -144,11 +138,11 @@ class PandocRuby
144
138
  # Example:
145
139
  #
146
140
  # PandocRuby.markdown("# text")
147
- # # => #<PandocRuby:0x007 @target="# text", @options=[{:from=>"markdown"}]
141
+ # # => #<PandocRuby:0x007 @input_string="# text", @options=[{:from=>"markdown"}]
148
142
  class << self
149
143
  READERS.each_key do |r|
150
144
  define_method(r) do |*args|
151
- args += [{:from => r}]
145
+ args += [{ :from => r }]
152
146
  new(*args)
153
147
  end
154
148
  end
@@ -165,107 +159,114 @@ class PandocRuby
165
159
  # # => "<h1 id=\"text\">text</h1>\n"
166
160
  WRITERS.each_key do |w|
167
161
  define_method(:"to_#{w}") do |*args|
168
- args += [{:to => w.to_sym}]
162
+ args += [{ :to => w.to_sym }]
169
163
  convert(*args)
170
164
  end
171
165
  end
172
166
 
173
- private
174
-
175
- # Sets the executable, which by default is `pandoc`. The `@executable`
176
- # variable can be set in the initializer, so testing for its presence first.
177
- # Finally, checking to see if the bin_path was set and, if so, using that.
178
- def executable
179
- @executable ||= 'pandoc'
180
- @@bin_path ? File.join(@@bin_path, @executable) : @executable
181
- end
167
+ private
182
168
 
183
- # Executes the pandoc command for binary writers. A temp file is created
184
- # and written to, then read back into the program as a string, then the
185
- # temp file is closed and unlinked.
186
- def convert_binary
187
- tmp_file = Tempfile.new('pandoc-conversion')
188
- begin
189
- self.options += [{:output => tmp_file.path}]
190
- self.option_string = "#{self.option_string} --output #{tmp_file.path}"
191
- execute(command_with_options)
192
- return IO.binread(tmp_file)
193
- ensure
194
- tmp_file.close
195
- tmp_file.unlink
169
+ # Execute the pandoc command for binary writers. A temp file is created
170
+ # and written to, then read back into the program as a string, then the
171
+ # temp file is closed and unlinked.
172
+ def convert_binary
173
+ tmp_file = Tempfile.new('pandoc-conversion')
174
+ begin
175
+ self.options += [{ :output => tmp_file.path }]
176
+ self.option_string = "#{self.option_string} --output #{tmp_file.path}"
177
+ execute("#{@@pandoc_path}#{self.option_string}")
178
+ return IO.binread(tmp_file)
179
+ ensure
180
+ tmp_file.close
181
+ tmp_file.unlink
182
+ end
196
183
  end
197
- end
198
184
 
199
- # Executes the pandoc command for btring writers.
200
- def convert_string
201
- execute(command_with_options)
202
- end
185
+ # Execute the pandoc command for string writers.
186
+ def convert_string
187
+ if ! @input_files.nil?
188
+ execute("#{@@pandoc_path} #{@input_files}#{self.option_string}")
189
+ else
190
+ execute("#{@@pandoc_path}#{self.option_string}")
191
+ end
192
+ end
203
193
 
204
- # Combines the executable string with the option string.
205
- def command_with_options
206
- executable + self.option_string
207
- end
194
+ # Run the command and returns the output.
195
+ def execute(command)
196
+ output = error = exit_status = nil
197
+ @timeout ||= 31_557_600 # A year should be enough?
198
+ Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
199
+ begin
200
+ Timeout.timeout(@timeout) do
201
+ unless @input_string.nil?
202
+ stdin.puts @input_string
203
+ stdin.close
204
+ end
205
+ output = stdout.read
206
+ error = stderr.read
207
+ exit_status = wait_thr.value
208
+ end
209
+ rescue Timeout::Error => ex
210
+ Process.kill 9, wait_thr.pid
211
+ maybe_ex = "\n#{ex}" if ex
212
+ error = "Pandoc timed out after #{@timeout} seconds.#{maybe_ex}"
213
+ end
214
+ end
208
215
 
209
- # Runs the command and returns the output.
210
- def execute(command)
211
- output = error = exit_status = nil
212
- Open3::popen3(command) do |stdin, stdout, stderr, wait_thr|
213
- stdin.puts @target
214
- stdin.close
215
- output = stdout.read
216
- error = stderr.read
217
- exit_status = wait_thr.value
216
+ raise error unless exit_status && exit_status.success?
217
+ output
218
218
  end
219
- raise error unless exit_status.success?
220
- output
221
- end
222
219
 
223
- # Builds the option string to be passed to pandoc by iterating over the
224
- # opts passed in. Recursively calls itself in order to handle hash options.
225
- def prepare_options(opts = [])
226
- opts.inject('') do |string, (option, value)|
227
- string += case
228
- when value
229
- create_option(option, value)
230
- when option.respond_to?(:each_pair)
231
- prepare_options(option)
232
- else
233
- create_option(option)
234
- end
220
+ # Builds the option string to be passed to pandoc by iterating over the
221
+ # opts passed in. Recursively calls itself in order to handle hash options.
222
+ def prepare_options(opts = [])
223
+ opts.inject('') do |string, (option, value)|
224
+ string += case
225
+ when value
226
+ create_option(option, value)
227
+ when option.respond_to?(:each_pair)
228
+ prepare_options(option)
229
+ else
230
+ create_option(option)
231
+ end
232
+ end
235
233
  end
236
- end
237
234
 
238
- # Takes a flag and optional argument, uses it to set any relevant options
239
- # used by the library, and returns string with the option formatted as a
240
- # command line options. If the option has an argument, it is also included.
241
- def create_option(flag, argument = nil)
242
- return if !flag
243
- flag = flag.to_s
244
- set_pandoc_ruby_options(flag, argument)
245
- if !!argument
246
- "#{format_flag(flag)} #{argument}"
247
- else
248
- format_flag(flag)
235
+ # Takes a flag and optional argument, uses it to set any relevant options
236
+ # used by the library, and returns string with the option formatted as a
237
+ # command line options. If the option has an argument, it is also included.
238
+ def create_option(flag, argument = nil)
239
+ return '' unless flag
240
+ flag = flag.to_s
241
+ set_pandoc_ruby_options(flag, argument)
242
+ return '' if flag == 'timeout' # pandoc doesn't accept timeouts yet
243
+ if !argument.nil?
244
+ "#{format_flag(flag)} #{argument}"
245
+ else
246
+ format_flag(flag)
247
+ end
249
248
  end
250
- end
251
249
 
252
- # Formats an option flag in order to be used with the pandoc command line
253
- # tool.
254
- def format_flag(flag)
255
- if flag.length == 1
256
- " -#{flag}"
257
- else
258
- " --#{flag.to_s.gsub(/_/, '-')}"
250
+ # Formats an option flag in order to be used with the pandoc command line
251
+ # tool.
252
+ def format_flag(flag)
253
+ if flag.length == 1
254
+ " -#{flag}"
255
+ else
256
+ " --#{flag.to_s.tr('_', '-')}"
257
+ end
259
258
  end
260
- end
261
259
 
262
- # Takes an option and optional argument and uses them to set any flags
263
- # used by PandocRuby.
264
- def set_pandoc_ruby_options(flag, argument = nil)
265
- if flag == 't' || flag == 'to'
266
- self.writer = argument.to_s
267
- self.binary_output = true if BINARY_WRITERS.keys.include?(self.writer)
260
+ # Takes an option and optional argument and uses them to set any flags
261
+ # used by PandocRuby.
262
+ def set_pandoc_ruby_options(flag, argument = nil)
263
+ case flag
264
+ when 't', 'to'
265
+ self.writer = argument.to_s
266
+ self.binary_output = true if BINARY_WRITERS.keys.include?(self.writer)
267
+ when 'timeout'
268
+ @timeout = argument
269
+ end
268
270
  end
269
- end
270
271
 
271
272
  end