pandoc-ruby 1.0.0 → 2.0.0

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