mmd-ruby 5.2.0.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.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +78 -0
  3. data/MultiMarkdown-5/src/GLibFacade.c +310 -0
  4. data/MultiMarkdown-5/src/GLibFacade.h +100 -0
  5. data/MultiMarkdown-5/src/beamer.c +182 -0
  6. data/MultiMarkdown-5/src/beamer.h +11 -0
  7. data/MultiMarkdown-5/src/critic.c +117 -0
  8. data/MultiMarkdown-5/src/critic.h +15 -0
  9. data/MultiMarkdown-5/src/glib.h +11 -0
  10. data/MultiMarkdown-5/src/html.c +1171 -0
  11. data/MultiMarkdown-5/src/html.h +14 -0
  12. data/MultiMarkdown-5/src/latex.c +1234 -0
  13. data/MultiMarkdown-5/src/latex.h +16 -0
  14. data/MultiMarkdown-5/src/libMultiMarkdown.h +257 -0
  15. data/MultiMarkdown-5/src/lyx.c +2269 -0
  16. data/MultiMarkdown-5/src/lyx.h +37 -0
  17. data/MultiMarkdown-5/src/lyxbeamer.c +265 -0
  18. data/MultiMarkdown-5/src/lyxbeamer.h +11 -0
  19. data/MultiMarkdown-5/src/memoir.c +80 -0
  20. data/MultiMarkdown-5/src/memoir.h +10 -0
  21. data/MultiMarkdown-5/src/multimarkdown.c +559 -0
  22. data/MultiMarkdown-5/src/odf.c +1241 -0
  23. data/MultiMarkdown-5/src/odf.h +18 -0
  24. data/MultiMarkdown-5/src/opml.c +189 -0
  25. data/MultiMarkdown-5/src/opml.h +15 -0
  26. data/MultiMarkdown-5/src/parse_utilities.c +912 -0
  27. data/MultiMarkdown-5/src/parser.c +17341 -0
  28. data/MultiMarkdown-5/src/parser.h +190 -0
  29. data/MultiMarkdown-5/src/rng.c +117 -0
  30. data/MultiMarkdown-5/src/rtf.c +665 -0
  31. data/MultiMarkdown-5/src/rtf.h +17 -0
  32. data/MultiMarkdown-5/src/strtok.c +56 -0
  33. data/MultiMarkdown-5/src/strtok.h +9 -0
  34. data/MultiMarkdown-5/src/text.c +56 -0
  35. data/MultiMarkdown-5/src/text.h +11 -0
  36. data/MultiMarkdown-5/src/toc.c +157 -0
  37. data/MultiMarkdown-5/src/toc.h +15 -0
  38. data/MultiMarkdown-5/src/transclude.c +335 -0
  39. data/MultiMarkdown-5/src/transclude.h +28 -0
  40. data/MultiMarkdown-5/src/version.h +59 -0
  41. data/MultiMarkdown-5/src/writer.c +767 -0
  42. data/MultiMarkdown-5/src/writer.h +38 -0
  43. data/README.md +77 -0
  44. data/Rakefile +88 -0
  45. data/bin/mmd-ruby +123 -0
  46. data/ext/extconf.h +3 -0
  47. data/ext/extconf.rb +10 -0
  48. data/ext/multimarkdown.c +133 -0
  49. data/lib/mmd-jekyll.rb +19 -0
  50. data/lib/mmd-ruby.rb +1 -0
  51. data/lib/mmd.rb +1 -0
  52. data/lib/multimarkdown-ruby.rb +1 -0
  53. data/lib/multimarkdown.bundle +0 -0
  54. data/lib/multimarkdown.rb +69 -0
  55. data/lib/multimarkdown/version.rb +6 -0
  56. data/mmd-ruby.gemspec +37 -0
  57. data/test/extensions_test.rb +174 -0
  58. data/test/multimarkdown_test.rb +77 -0
  59. metadata +120 -0
@@ -0,0 +1,38 @@
1
+ #include "parser.h"
2
+
3
+ #include "text.h"
4
+ #include "html.h"
5
+ #include "latex.h"
6
+ #include "memoir.h"
7
+ #include "beamer.h"
8
+ #include "lyx.h"
9
+ #include "lyxbeamer.h"
10
+ #include "opml.h"
11
+ #include "odf.h"
12
+ #include "rtf.h"
13
+ #include "critic.h"
14
+ #include "toc.h"
15
+
16
+ char * export_node_tree(node *list, int format, unsigned long extensions);
17
+
18
+ void extract_references(node *list, scratch_pad *scratch);
19
+ void extract_abbreviations(node *list, scratch_pad *scratch);
20
+ void find_abbreviations(node *list, scratch_pad *scratch);
21
+
22
+ link_data * extract_link_data(char *label, scratch_pad *scratch);
23
+
24
+ void pad(GString *out, int num, scratch_pad *scratch);
25
+
26
+ int note_number_for_label(char *text, scratch_pad *scratch);
27
+ int note_number_for_node(node *ref, scratch_pad *scratch);
28
+ node * node_matching_label(char *label, node *n);
29
+ int count_node_from_end(node *n);
30
+ int cite_count_node_from_end(node *n);
31
+ node * node_for_count(node *n, int count);
32
+ void move_note_to_used(node *list, scratch_pad *scratch);
33
+ void use_inline_footnote(node *ref, scratch_pad *scratch);
34
+ node * node_for_attribute(char *querystring, node *list);
35
+
36
+ char * dimension_for_attribute(char *querystring, node *list);
37
+
38
+ link_data * load_link_data(node *n, scratch_pad *scratch);
@@ -0,0 +1,77 @@
1
+ mmd-ruby - MultiMarkdown for Ruby
2
+ =================================
3
+
4
+ A Ruby wrapper for [Fletcher Penney's MultiMarkdown](http://github.com/fletcher/MultiMarkdown-5/)
5
+ C library. Based on [rmultimarkdown by Till Schulte-Coerne](http://github.com/tillsc/multimarkdown/)
6
+
7
+ How to use?
8
+ -----------
9
+
10
+ >> require 'mmd-ruby' or require 'mmd' or require 'multimarkdown' or require 'multimarkdown-ruby'
11
+
12
+ Parse (output HTML):
13
+ >> MultiMarkdown.new('Hello, world.').to_html
14
+ #=> "<p>Hello, world.</p>"
15
+
16
+ Parse with Extensions:
17
+ >> MultiMarkdown.new('_Hello World!_', :smart, :filter_html).to_html
18
+ #=> "<p><em>Hello World!</em></p>"
19
+
20
+ *Available Extensions:
21
+ :compatibility - Markdown compatibility mode (disables all other options)
22
+ :complete - Force complete document
23
+ :snippet - Force snippet only
24
+ :no_smart_quotes - Disable Smart quotes
25
+ :no_footnotes - Disable Footnotes
26
+ :no_anchors - Don't add anchors to headers, etc.
27
+ :filter_styles - Filter out style blocks
28
+ :filter_html - Filter out raw HTML
29
+ :process_html - Process Markdown inside HTML
30
+ :no_metadata - Don't parse Metadata
31
+ :obfuscate_email_addresses - Mask email addresses
32
+ :critic_markup_accept_all - CriticMarkup: Accept all proposed changes
33
+ :critic_markup_reject_all - CriticMarkup: Reject all proposed changes
34
+ :random_footnote_anchor_numbers - Use random numbers for footnote link anchors
35
+ :escaped_line_breaks - Escaped line breaks
36
+
37
+ Parse (output LaTeX):
38
+ >> MultiMarkdown.new('_Hello World!_').to_latex
39
+ #=> "\emph{Hello World!}"
40
+
41
+ Add Metadata:
42
+ >> doc = MultiMarkdown.new("Title: Some document \n\nSome text in the document")
43
+
44
+ Extract All Metadata:
45
+ >> doc.metadata
46
+ #=> {"title" => "Some document"}
47
+
48
+ Extract Metadata Value by Key:
49
+ >> doc.metadata("Title")
50
+ #=> "Some document"
51
+
52
+ See the [MultiMarkdown User's Guide](http://fletcher.github.io/MultiMarkdown-5/) for more information.
53
+
54
+ Installation
55
+ ------------
56
+ Install from [Rubygems](http://rubygems.org/gems/mmd-ruby):
57
+
58
+ $ [sudo] gem install mmd-ruby
59
+
60
+ Bundle via [Bundler](http://bundler.io):
61
+
62
+ gem 'mmd-ruby'
63
+
64
+ Changelog
65
+ -------
66
+
67
+ **Beware**: The versioning scheme isn't based upon
68
+ [Semantic Versioning](http://semver.org)! The first three version numbers are
69
+ inherited from the underlying C library. Only the last number is used to indicate
70
+ changes in the Ruby wrapper itself.
71
+
72
+ * [5.2.0.1](tree/v5.2.0.1): Initial Release. Based on MultiMarkdown 5.2.0.
73
+
74
+ License
75
+ -------
76
+ MultiMarkdown and mmd-ruby are both licensed under the MIT License.
77
+ See [LICENSE](LICENSE) for more information.
@@ -0,0 +1,88 @@
1
+ require 'rake/clean'
2
+ require 'rdoc/task'
3
+ require 'bundler'
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ task :default => "test:unit"
8
+
9
+ # ***** Build
10
+
11
+ DLEXT = RbConfig::CONFIG['DLEXT']
12
+
13
+ # For Mac OS X -- prevents prevent additional ._* files being added to tarball
14
+ ENV['COPYFILE_DISABLE'] = 'true'
15
+
16
+ namespace "MultiMarkdown-5" do
17
+
18
+ desc "Initialize the submodule"
19
+ task "init" => "generate_parser"
20
+
21
+ desc "Generate needed parser files"
22
+ task "generate_parser" do
23
+ chdir('MultiMarkdown-5') do
24
+ sh 'make src/parser.c'
25
+ sh 'make src/version.h'
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+
32
+ file 'ext/Makefile' => ["MultiMarkdown-5:init"] + FileList['ext/{extconf.rb,*.c,*.h,*.rb}', 'MultiMarkdown-5/src/*.{c,h}', 'MultiMarkdown-5/build/*.{c,h}'] do
33
+ chdir('ext') do
34
+ ruby 'extconf.rb'
35
+ end
36
+ end
37
+ CLEAN.include 'ext/Makefile'
38
+
39
+ file "ext/multimarkdown.#{DLEXT}" => FileList['ext/Makefile', 'ext/*.{c,h,rb}', 'MultiMarkdown-5/src/*.{c,h}', 'MultiMarkdown-5/build/*.{c,h}'] do |f|
40
+ chdir('ext') do
41
+ sh 'make'
42
+ end
43
+ end
44
+ CLEAN.include 'ext/*.{o,bundle,so}'
45
+ CLEAN.include 'MultiMarkdown-5/src/*.o'
46
+
47
+ file "lib/multimarkdown.#{DLEXT}" => "ext/multimarkdown.#{DLEXT}" do |f|
48
+ cp f.prerequisites, "lib/", :preserve => true
49
+ end
50
+ CLEAN.include "lib/*.{so,bundle}"
51
+
52
+ desc 'Build the multimarkdown extension'
53
+ task :build => "lib/multimarkdown.#{DLEXT}"
54
+
55
+ # ***** Test
56
+
57
+ desc 'Run unit and conformance tests'
58
+ task :test => [ 'test:unit', 'test:conformance' ]
59
+
60
+ namespace :test do
61
+
62
+ desc 'Run unit tests'
63
+ task :unit => :build do |t|
64
+ FileList['test/*.rb'].each do |f|
65
+ ruby f
66
+ end
67
+ end
68
+
69
+ desc "Run conformance tests"
70
+ task :conformance => :build do |t|
71
+ script = "#{pwd}/bin/mmd-ruby"
72
+ chdir("MultiMarkdown-5/submodules/MarkdownTest") do
73
+ sh "./MarkdownTest.pl --script='#{script}' --flags='-c' --tidy"
74
+ sh "./MarkdownTest.pl --script='#{script}' --testdir='MultiMarkdownTests'"
75
+ sh "./MarkdownTest.pl --script='#{script}' --testdir='MultiMarkdownTests' --flags='-t latex' --ext='.tex'"
76
+ sh "./MarkdownTest.pl --script='#{script}' --testdir='BeamerTests' --flags='-t latex' --ext='.tex'"
77
+ sh "./MarkdownTest.pl --script='#{script}' --testdir='MemoirTests' --flags='-t latex' --ext='.tex'"
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ # ***** RDoc
84
+
85
+ Rake::RDocTask.new do |rd|
86
+ rd.main = "README.md"
87
+ rd.rdoc_files.include("README.md", "ext/**/*.c", "lib/**/*.rb")
88
+ end
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'multimarkdown'
5
+ rescue LoadError => boom
6
+ local_path = File.expand_path(File.dirname(__FILE__))
7
+ $: << "#{local_path}/../lib"
8
+ require 'multimarkdown'
9
+ end
10
+
11
+ # Option parser -- http://florianpilz.github.com/micro-optparse/
12
+
13
+ require 'ostruct'
14
+ require 'optparse'
15
+
16
+ class Parser
17
+ attr_accessor :banner, :version
18
+ def initialize
19
+ @options = []
20
+ @used_short = []
21
+ yield self if block_given?
22
+ end
23
+
24
+ def option(name, desc, settings = {})
25
+ @options << [name, desc, settings]
26
+ end
27
+
28
+ def short_from(name)
29
+ name.to_s.chars.each do |c|
30
+ next if @used_short.include?(c) || c == "_"
31
+ return c # returns from short_from method
32
+ end
33
+ nil
34
+ end
35
+
36
+ def validate(options) # remove this method if you want fewer lines of code and don't need validations
37
+ options.each_pair do |key, value|
38
+ opt = @options.find_all{ |o| o[0] == key }.first
39
+ key = "--" << key.to_s.gsub("_", "-")
40
+ unless opt[2][:value_in_set].nil? || opt[2][:value_in_set].include?(value)
41
+ puts "Parameter for #{key} must be in [" << opt[2][:value_in_set].join(", ") << "]" ; exit(1)
42
+ end
43
+ unless opt[2][:value_matches].nil? || opt[2][:value_matches] =~ value
44
+ puts "Parameter for #{key} must match /" << opt[2][:value_matches].source << "/" ; exit(1)
45
+ end
46
+ unless opt[2][:value_satisfies].nil? || opt[2][:value_satisfies].call(value)
47
+ puts "Parameter for #{key} must satisfy given conditions (see description)" ; exit(1)
48
+ end
49
+ end
50
+ end
51
+
52
+ def process!(arguments = ARGV)
53
+ @result = (@default_values || {}).clone # reset or new
54
+ @optionparser ||= OptionParser.new do |p| # prepare only once
55
+ @options.each do |o|
56
+ @used_short << short = o[2][:short] == false ? nil : o[2][:short] || short_from(o[0])
57
+ @result[o[0]] = o[2][:default] || false # set default
58
+ klass = o[2][:default].class == Fixnum ? Integer : o[2][:default].class
59
+ desk = o[1] + (o[2][:nodefault] ? "" : " (default is #{@result[o[0]]})")
60
+ if [TrueClass, FalseClass, NilClass].include?(klass) # boolean switch
61
+ p.on(short && "-" << short, "--" << o[0].to_s.gsub("_", "-"), desk) {|x| @result[o[0]] = x}
62
+ else # argument with parameter
63
+ p.on(short && "-" << short, "--" << o[0].to_s.gsub("_", "-") << " " << (o[2][:name] ? "[#{o[2][:name].to_s}]" : ""), klass, desk) {|x| @result[o[0]] = x}
64
+ end
65
+ end
66
+
67
+ p.banner = @banner unless @banner.nil?
68
+ p.on_tail("-h", "--help", "Show this message") {puts p ; exit}
69
+ short = @used_short.include?("v") ? "-V" : "-v"
70
+ p.on_tail(short, "--version", "Print version") {puts @version ; exit} unless @version.nil?
71
+ @default_values = @result.clone # save default values to reset @result in subsequent calls
72
+ end
73
+
74
+ begin
75
+ @optionparser.parse!(arguments)
76
+ rescue OptionParser::ParseError => e
77
+ puts e.message ; exit(1)
78
+ end
79
+
80
+ validate(@result) if self.respond_to?("validate")
81
+ @result
82
+ end
83
+ end
84
+
85
+ # Parse options
86
+ options = Parser.new do |p|
87
+ p.banner = "Ruby wrapper for MultiMarkdown"
88
+ p.version = "mmd-ruby #{MultiMarkdown::VERSION}"
89
+ p.option :output, "send output to FILE (default is stdout)", :name => "FILE", :default => "", :nodefault => true, :short => "o"
90
+ p.option :to, "convert to FORMAT", :name => "FORMAT", :default => "html", :value_in_set => ["html","latex"], :short => "t"
91
+ p.option :extract, "extract and display metadata specified by KEY", :name => "KEY", :default => "", :nodefault => true, :short => "e"
92
+ MultiMarkdown::EXTENSIONS.each do |ext, opts|
93
+ p.option ext.to_sym, opts[:desc], :default => false, :short => opts[:short] || false
94
+ end
95
+ end.process!
96
+
97
+ # Convert options to MultiMarkdown module's options
98
+ mmopts = []
99
+ MultiMarkdown::EXTENSIONS.each do |ext, description|
100
+ mmopts << ext.to_sym if options[ext.to_sym]
101
+ end
102
+
103
+ # ARGV will now only contain input filename, if it contains anything
104
+ STDIN.reopen(ARGV[0], 'rb') if ARGV.any?
105
+ multimarkdown = MultiMarkdown.new(STDIN.read,*mmopts)
106
+ STDOUT.reopen(options[:output], 'w') if options[:output]!=""
107
+
108
+ # Print specified metadata if requested
109
+ if options[:extract]!=""
110
+ puts multimarkdown.extract_metadata(options[:extract])
111
+ exit(0)
112
+ end
113
+
114
+ # Do processing
115
+ case options[:to]
116
+ when "html"
117
+ STDOUT.write(multimarkdown.to_html)
118
+ when "latex"
119
+ STDOUT.write(multimarkdown.to_latex)
120
+ else
121
+ puts "Output other than html & latex not currently supported"
122
+ exit(1)
123
+ end
@@ -0,0 +1,3 @@
1
+ #ifndef EXTCONF_H
2
+ #define EXTCONF_H
3
+ #endif
@@ -0,0 +1,10 @@
1
+ require 'mkmf'
2
+
3
+ dir_config('multimarkdown')
4
+
5
+ mmd_objs = %w[parse_utilities.o parser.o GLibFacade.o writer.o text.o html.o latex.o memoir.o beamer.o lyx.o lyxbeamer.o opml.o odf.o critic.o rng.o rtf.o transclude.o]
6
+
7
+ $objs = mmd_objs.map { |s| "../MultiMarkdown-5/src/#{s}" } + ["multimarkdown.o"]
8
+
9
+ create_header
10
+ create_makefile('multimarkdown')
@@ -0,0 +1,133 @@
1
+ #include "ruby.h"
2
+ #include <ruby/encoding.h>
3
+
4
+ #include "../MultiMarkdown-5/src/parser.h"
5
+
6
+ // Tries to convert a C string into an encoded ruby String
7
+ static VALUE encoded_str_new2(char *str, char *encoding) {
8
+ VALUE result = rb_str_new2(str);
9
+
10
+ int enc = rb_enc_find_index(encoding);
11
+ if (enc > 0) {
12
+ rb_enc_associate_index(result, enc);
13
+ }
14
+
15
+ return result;
16
+ }
17
+
18
+ static VALUE rb_cMultiMarkdown;
19
+
20
+ static int get_exts(VALUE self) {
21
+ int extensions = 0;
22
+ if (rb_funcall(self, rb_intern("complete"), 0) == Qtrue)
23
+ extensions = extensions | EXT_COMPLETE;
24
+ if (rb_funcall(self, rb_intern("snippet"), 0) == Qtrue)
25
+ extensions = extensions | EXT_SNIPPET;
26
+ if (rb_funcall(self, rb_intern("no_smart_quotes"), 0) != Qtrue)
27
+ extensions = extensions | EXT_SMART;
28
+ if (rb_funcall(self, rb_intern("no_footnotes"), 0) != Qtrue)
29
+ extensions = extensions | EXT_NOTES;
30
+ if (rb_funcall(self, rb_intern("no_anchors"), 0) == Qtrue)
31
+ extensions = extensions | EXT_NO_LABELS;
32
+ if (rb_funcall(self, rb_intern("filter_styles"), 0) == Qtrue)
33
+ extensions = extensions | EXT_FILTER_STYLES;
34
+ if (rb_funcall(self, rb_intern("filter_html"), 0) == Qtrue)
35
+ extensions = extensions | EXT_FILTER_HTML;
36
+ if (rb_funcall(self, rb_intern("process_html"), 0) == Qtrue)
37
+ extensions = extensions | EXT_PROCESS_HTML;
38
+ if (rb_funcall(self, rb_intern("no_metadata"), 0) == Qtrue)
39
+ extensions = extensions | EXT_NO_METADATA;
40
+ if (rb_funcall(self, rb_intern("obfuscate_email_addresses"), 0) == Qtrue)
41
+ extensions = extensions | EXT_OBFUSCATE;
42
+ if (rb_funcall(self, rb_intern("critic_markup_accept_all"), 0) == Qtrue)
43
+ extensions = extensions | EXT_CRITIC | EXT_CRITIC_ACCEPT;
44
+ if (rb_funcall(self, rb_intern("critic_markup_reject_all"), 0) == Qtrue)
45
+ extensions = extensions | EXT_CRITIC | EXT_CRITIC_REJECT;
46
+ if (rb_funcall(self, rb_intern("random_footnote_anchor_numbers"), 0) == Qtrue)
47
+ extensions = extensions | EXT_RANDOM_FOOT;
48
+ if (rb_funcall(self, rb_intern("escaped_line_breaks"), 0) == Qtrue)
49
+ extensions = extensions | EXT_ESCAPED_LINE_BREAKS;
50
+
51
+ /* Compatibility overwrites all other extensions */
52
+ if (rb_funcall(self, rb_intern("compatibility"), 0) == Qtrue)
53
+ extensions = EXT_COMPATIBILITY;
54
+ return extensions;
55
+ }
56
+
57
+ char *get_text(VALUE self) {
58
+ /* grab char pointer to multimarkdown input text */
59
+ VALUE text = rb_iv_get(self, "@text");
60
+ Check_Type(text, T_STRING);
61
+ return StringValuePtr(text);
62
+ }
63
+
64
+ static VALUE rb_multimarkdown_to_html(VALUE self) {
65
+ char *html = markdown_to_string(get_text(self), get_exts(self), HTML_FORMAT);
66
+ VALUE result = encoded_str_new2(html, "UTF-8");
67
+ free(html);
68
+
69
+ return result;
70
+ }
71
+
72
+ static VALUE rb_multimarkdown_to_latex(VALUE self) {
73
+ char *latex = markdown_to_string(get_text(self), get_exts(self), LATEX_FORMAT);
74
+ VALUE result = encoded_str_new2(latex, "UTF-8");
75
+ free(latex);
76
+
77
+ return result;
78
+ }
79
+
80
+ static VALUE rb_multimarkdown_extract_metadata_keys(VALUE self) {
81
+ char *metadata_keys = extract_metadata_keys(get_text(self), get_exts(self));
82
+ VALUE str = encoded_str_new2(metadata_keys, "UTF-8");
83
+ free(metadata_keys);
84
+
85
+ return rb_funcall(str, rb_intern("split"), 1, rb_str_new2("\n"));
86
+ }
87
+
88
+ static VALUE rb_multimarkdown_extract_metadata_value(VALUE self, VALUE key) {
89
+ Check_Type(key, T_STRING);
90
+ char *pkey = StringValuePtr(key);
91
+
92
+ char *metadata = extract_metadata_value(get_text(self), get_exts(self), pkey);
93
+ VALUE result = encoded_str_new2(metadata, "UTF-8");
94
+ free(metadata);
95
+
96
+ return result;
97
+ }
98
+
99
+ void Init_multimarkdown() {
100
+
101
+ rb_cMultiMarkdown = rb_define_class("MultiMarkdown", rb_cObject);
102
+
103
+ /* Document-method: MultiMarkdown#to_html
104
+ *
105
+ * Return string containing HTML generated from MultiMarkdown text
106
+ */
107
+ rb_define_method(rb_cMultiMarkdown, "to_html", rb_multimarkdown_to_html, 0);
108
+
109
+ /* Document-method: MultiMarkdown#to_latex
110
+ *
111
+ * Return string containing latex generated from MultiMarkdown text
112
+ */
113
+ rb_define_method(rb_cMultiMarkdown, "to_latex", rb_multimarkdown_to_latex, 0);
114
+
115
+ /* Document-method: MultiMarkdown#extract_metadata_keys
116
+ *
117
+ * Return Array of metadata keys
118
+ */
119
+ rb_define_method(rb_cMultiMarkdown, "extract_metadata_keys", rb_multimarkdown_extract_metadata_keys, 0);
120
+
121
+ /* Document-method: MultiMarkdown#extract_metadata_value
122
+ * :call-seq: extract_metadata_value(key)
123
+ *
124
+ * Fetches metadata specified by +key+ from MultiMarkdown text
125
+ */
126
+ rb_define_method(rb_cMultiMarkdown, "extract_metadata_value", rb_multimarkdown_extract_metadata_value, 1);
127
+
128
+ rb_define_const(rb_cMultiMarkdown, "MMD_VERSION", rb_str_new2("5.2.0"));
129
+ /* Document-const: MultiMarkdown::MMD_VERSION
130
+ *
131
+ * The version of the MultiMarkdown library
132
+ */
133
+ }