minidown 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.travis.yml +9 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +73 -0
  7. data/Rakefile +4 -0
  8. data/bin/minidown +33 -0
  9. data/lib/minidown.rb +13 -0
  10. data/lib/minidown/document.rb +142 -0
  11. data/lib/minidown/element.rb +40 -0
  12. data/lib/minidown/elements.rb +15 -0
  13. data/lib/minidown/elements/block_element.rb +37 -0
  14. data/lib/minidown/elements/code_block_element.rb +44 -0
  15. data/lib/minidown/elements/dividing_line_element.rb +11 -0
  16. data/lib/minidown/elements/html_element.rb +22 -0
  17. data/lib/minidown/elements/indent_code_element.rb +23 -0
  18. data/lib/minidown/elements/line_element.rb +28 -0
  19. data/lib/minidown/elements/list_element.rb +36 -0
  20. data/lib/minidown/elements/list_group_element.rb +87 -0
  21. data/lib/minidown/elements/order_list_element.rb +20 -0
  22. data/lib/minidown/elements/paragraph_element.rb +56 -0
  23. data/lib/minidown/elements/raw_html_element.rb +11 -0
  24. data/lib/minidown/elements/table_element.rb +80 -0
  25. data/lib/minidown/elements/text_element.rb +198 -0
  26. data/lib/minidown/elements/unorder_list_element.rb +31 -0
  27. data/lib/minidown/html_helper.rb +18 -0
  28. data/lib/minidown/parser.rb +19 -0
  29. data/lib/minidown/utils.rb +28 -0
  30. data/lib/minidown/version.rb +3 -0
  31. data/minidown.gemspec +26 -0
  32. data/spec/blank_line_spec.rb +21 -0
  33. data/spec/code_block_spec.rb +182 -0
  34. data/spec/dividing_line_spec.rb +35 -0
  35. data/spec/h1_and_h2_spec.rb +55 -0
  36. data/spec/indent_block_spec.rb +17 -0
  37. data/spec/li_spec.rb +354 -0
  38. data/spec/minidown_spec.rb +12 -0
  39. data/spec/paragraph_spec.rb +17 -0
  40. data/spec/raw_html_spec.rb +43 -0
  41. data/spec/spec_helper.rb +2 -0
  42. data/spec/start_with_gt_spec.rb +70 -0
  43. data/spec/start_with_shape_spec.rb +42 -0
  44. data/spec/table_spec.rb +63 -0
  45. data/spec/task_list_spec.rb +18 -0
  46. data/spec/text_element_spec.rb +317 -0
  47. metadata +175 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5e0c5db00609072309a70d35274f0c843260c597
4
+ data.tar.gz: f11dd0d634f65eaa9a2f51cf33af9019d47b3dd6
5
+ SHA512:
6
+ metadata.gz: 9de43a1127d5696dc021d25d62cd4268960c50ecf61f287e16098935faa987e6f5b7abd344164a2443cf1fe83da2283a86c698da38e31ada1a4a26fe0db7980f
7
+ data.tar.gz: f07ad8b5108ec18e4180681d9f46d8415ae8997dc50d1eb887bb59a868985b9e63ccfba18f4ae158282bb23cac3f6f2c7dd5075c4a60e1a4b71ab31012324130
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *~
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - ruby-head
7
+ matrix:
8
+ allow_failures:
9
+ - rvm: ruby-head
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in minidown.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,73 @@
1
+ Minidown
2
+ ================================
3
+ [![Gem Version](https://badge.fury.io/rb/minidown.png)](http://rubygems.org/gems/minidown)
4
+ [![Build Status](https://travis-ci.org/jjyr/minidown.png?branch=master)](https://travis-ci.org/jjyr/minidown)
5
+
6
+ Minidown is yet another markdown parser, with:
7
+
8
+ * **Complete** [GFM](https://help.github.com/articles/github-flavored-markdown) support.
9
+
10
+ * **Lightweight**, no other dependencies.
11
+
12
+ * Fast & **easy** to use.
13
+
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ gem 'minidown'
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install minidown
28
+
29
+ ## Basic usage
30
+
31
+ ```ruby
32
+ require 'minidown'
33
+
34
+ Minidown.render('*hello*')
35
+ #=> "<p><em>hello</em></p>"
36
+ ```
37
+
38
+ ## Custom your own handler
39
+
40
+ ```ruby
41
+ highlight_with_pygments = ->(lang, content) {
42
+ Pygments.highlight(content, :lexer => lang)
43
+ }
44
+
45
+ Minidown.render source, code_block_handler: highlight_with_pygments
46
+
47
+ # if you don't like pass options every time
48
+ parser_with_highlight = Minidown::Parser.new code_block_handler: highlight_with_pygments
49
+ parser_with_highlight.render source
50
+ ```
51
+
52
+ ## Command line
53
+
54
+ ```
55
+ wget https://raw.github.com/mojombo/github-flavored-markdown/gh-pages/_site/sample_content.md
56
+ minidown sample_content.md > result.html
57
+ open result.html
58
+ ```
59
+ looks nice!
60
+
61
+ ## Syntax
62
+
63
+ Complete **GFM**(GitHub Flavored Markdown) support.
64
+ include **Basic markdown**, **Task list**, **Table**, **Code**, **Blockquote** etc..
65
+ [view details](https://help.github.com/articles/github-flavored-markdown)
66
+
67
+ ## Contributing
68
+
69
+ 1. Fork it
70
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
71
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
72
+ 4. Push to the branch (`git push origin my-new-feature`)
73
+ 5. Create new Pull Request
@@ -0,0 +1,4 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+ RSpec::Core::RakeTask.new
4
+ task default: :spec
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'minidown'
4
+ require 'optparse'
5
+
6
+ Banner =<<BANNER
7
+ Minidown is a lightweight & fast markdown parser, with complete GFM support.
8
+
9
+ Usage:
10
+ minidown [FILE]
11
+ BANNER
12
+ OptionParser.new do |opts|
13
+ opts.banner = Banner
14
+
15
+ opts.on_tail "-v", "--version", "Show current version" do |v|
16
+ puts Minidown::VERSION
17
+ exit
18
+ end
19
+
20
+ opts.on_tail "-h", "--help", "Show this message" do |v|
21
+ puts opts
22
+ exit
23
+ end
24
+ end.parse!
25
+
26
+ file = ARGV.first
27
+ if file
28
+ puts Minidown.render(open(file).read)
29
+ else
30
+ $stderr.puts Banner
31
+ $stderr.puts "\nNo [FILE] argument, exit"
32
+ exit 1
33
+ end
@@ -0,0 +1,13 @@
1
+ require "minidown/version"
2
+ require 'minidown/parser'
3
+ require 'minidown/utils'
4
+ require 'minidown/elements'
5
+ require 'minidown/document'
6
+
7
+ module Minidown
8
+ class << self
9
+ def render str, options = {}
10
+ Parser.new(options).render str
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,142 @@
1
+ module Minidown
2
+ class Document
3
+ attr_accessor :lines, :nodes, :links_ref, :options
4
+ attr_reader :within_block
5
+
6
+ RefRegexp = {
7
+ link_ref_define: /\A\s*\[(.+)\]\:\s+(\S+)\s*(.*)/,
8
+ link_title: /((?<=\").+?(?=\"))/
9
+ }
10
+
11
+ TagRegexp ={
12
+ h1h6: /\Ah[1-6]\z/
13
+ }
14
+
15
+ def initialize lines, options = {}
16
+ @options = options
17
+ @lines = lines
18
+ @nodes = []
19
+ @within_block = false
20
+ @links_ref = {}
21
+ end
22
+
23
+ def parse
24
+ parse_references
25
+
26
+ while line = @lines.shift
27
+ parse_line line
28
+ end
29
+ end
30
+
31
+ def to_html
32
+ @html ||= (doc = ''
33
+ @nodes.each{|e| doc << e.to_html}
34
+ doc)
35
+ end
36
+
37
+ # define short methods
38
+ {text: TextElement, html_tag: HtmlElement, newline: LineElement, block: BlockElement, paragraph: ParagraphElement, ul: UnorderListElement, ol: OrderListElement, code_block: CodeBlockElement, dividing_line: DividingLineElement, indent_code: IndentCodeElement}.each do |name, klass|
39
+ define_method name do |*args|
40
+ klass.new(self, *args).parse
41
+ end
42
+ end
43
+
44
+ def parse_references
45
+ while line = @lines.pop
46
+ line.gsub! RefRegexp[:link_ref_define] do
47
+ id, url = $1, $2
48
+ $3 =~ RefRegexp[:link_title]
49
+ title = $1
50
+ links_ref[id.downcase] = {url: url, title: title}
51
+ ''
52
+ end
53
+ unless line.empty?
54
+ @lines << line
55
+ break
56
+ end
57
+ end
58
+ end
59
+
60
+ def parse_line line
61
+ regexp = Minidown::Utils::Regexp
62
+ case
63
+ when regexp[:blank_line] =~ line
64
+ # blankline
65
+ newline line
66
+ when !pre_blank? && (result = regexp[:h1_or_h2] =~ line; next_line = $2; result) && ParagraphElement === nodes.last
67
+ # ======== or -------
68
+ break_if_list line do
69
+ lines.unshift next_line if next_line && !next_line.empty?
70
+ html_tag nodes.pop, (line[0] == '='.freeze ? 'h1'.freeze : 'h2'.freeze)
71
+ end
72
+ when regexp[:start_with_shape] =~ line
73
+ # ####h4
74
+ break_if_list line do
75
+ text $2
76
+ html_tag nodes.pop, "h#{$1.size}"
77
+ end
78
+ when regexp[:start_with_quote] =~ line
79
+ # > blockquote
80
+ inblock{block $1}
81
+ when regexp[:dividing_line] =~ line
82
+ # * * * - - -
83
+ break_if_list line do
84
+ dividing_line line
85
+ end
86
+ when regexp[:unorder_list] =~ line
87
+ # * + -
88
+ indent, str = $1.size, $2
89
+ inblock{ul str, indent}
90
+ when regexp[:order_list] =~ line
91
+ # 1. order
92
+ indent, str = $1.size, $2
93
+ inblock{ol str, indent}
94
+ when regexp[:code_block] =~ line
95
+ # ``` or ~~~
96
+ inblock{code_block $1}
97
+ when !@within_block && pre_blank? && regexp[:indent_code] =~ line
98
+ # code
99
+ indent_code $1
100
+ when regexp[:pipe_symbol] =~ line && regexp[:table] =~ line
101
+ # column1 | column2 | ...
102
+ table = TableElement.new self, line, $1
103
+ raw_column_spec = @lines.shift
104
+ if table.check_column_spec raw_column_spec
105
+ inblock{table.parse}
106
+ else
107
+ @lines.unshift raw_column_spec if raw_column_spec
108
+ paragraph line
109
+ end
110
+ else
111
+ # paragraph
112
+ paragraph line
113
+ end
114
+ end
115
+
116
+ private
117
+ def pre_blank?
118
+ node = @nodes.last
119
+ node.nil? || node.blank?
120
+ end
121
+
122
+ def inblock
123
+ if @within_block
124
+ yield
125
+ else
126
+ @within_block = true
127
+ yield
128
+ @within_block = false
129
+ end
130
+ end
131
+
132
+ def break_if_list line
133
+ node = nodes.last
134
+ if @within_block && (UnorderListElement === node || OrderListElement === node)
135
+ @lines.unshift line
136
+ nodes << nil
137
+ else
138
+ yield
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,40 @@
1
+ require 'minidown/html_helper'
2
+
3
+ module Minidown
4
+ class Element
5
+ attr_accessor :content, :doc, :nodes, :children
6
+
7
+ include HtmlHelper
8
+
9
+ def raw_content
10
+ @content
11
+ end
12
+
13
+ def raw_content= str
14
+ @content = str
15
+ end
16
+
17
+ def unparsed_lines
18
+ doc.lines
19
+ end
20
+
21
+ def initialize doc, content
22
+ @doc = doc
23
+ @nodes = doc.nodes
24
+ @content = content
25
+ @children = []
26
+ end
27
+
28
+ def parse
29
+ raise NotImplementedError, 'method parse not implemented'
30
+ end
31
+
32
+ def to_html
33
+ raise NotImplementedError, 'method to_html not implemented'
34
+ end
35
+
36
+ def blank?
37
+ false
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,15 @@
1
+ require 'minidown/element'
2
+ require 'minidown/elements/raw_html_element'
3
+ require 'minidown/elements/html_element'
4
+ require 'minidown/elements/line_element'
5
+ require 'minidown/elements/text_element'
6
+ require 'minidown/elements/block_element'
7
+ require 'minidown/elements/table_element'
8
+ require 'minidown/elements/paragraph_element'
9
+ require 'minidown/elements/list_element'
10
+ require 'minidown/elements/list_group_element'
11
+ require 'minidown/elements/unorder_list_element'
12
+ require 'minidown/elements/order_list_element'
13
+ require 'minidown/elements/code_block_element'
14
+ require 'minidown/elements/dividing_line_element'
15
+ require 'minidown/elements/indent_code_element'
@@ -0,0 +1,37 @@
1
+ module Minidown
2
+ class BlockElement < Element
3
+ BlockTagRegexp = /\A\s*\>\s*/
4
+
5
+ def parse
6
+ unparsed_lines.unshift content
7
+ nodes << self
8
+ while(child_line = unparsed_lines.shift) do
9
+ block = child_line.sub! BlockTagRegexp, ''
10
+ doc.parse_line(child_line)
11
+ child = nodes.pop
12
+ case child
13
+ when LineElement
14
+ unparsed_lines.unshift child_line
15
+ unparsed_lines.unshift nil
16
+ when ParagraphElement
17
+ child.extra = !!block
18
+ nodes << child
19
+ else
20
+ break if child.nil?
21
+ nodes << child
22
+ end
23
+ end
24
+ children_range = (nodes.index(self) + 1)..-1
25
+ self.children = nodes[children_range]
26
+ nodes[children_range] = []
27
+ end
28
+
29
+ def to_html
30
+ build_tag 'blockquote'.freeze do |content|
31
+ children.each do |child|
32
+ content << child.to_html
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,44 @@
1
+ module Minidown
2
+ class CodeBlockElement < Element
3
+
4
+ def initialize *_
5
+ super
6
+ @code_block_handler = doc.options[:code_block_handler]
7
+ end
8
+
9
+ def parse
10
+ nodes << self
11
+ while(line = unparsed_lines.shift) do
12
+ case line
13
+ when Utils::Regexp[:code_block]
14
+ break
15
+ else
16
+ child = TextElement.new(doc, line)
17
+ child.escape = false
18
+ child.sanitize = @code_block_handler.nil?
19
+ child.convert = false
20
+ children << child
21
+ end
22
+ end
23
+ end
24
+
25
+ def lang
26
+ @lang ||= content.empty? ? nil : content
27
+ end
28
+
29
+ def children_html
30
+ children.map(&:to_html).join("\n".freeze)
31
+ end
32
+
33
+ def to_html
34
+ if @code_block_handler
35
+ @code_block_handler.call(lang, children_html).to_s
36
+ else
37
+ attr = lang ? {class: lang} : nil
38
+ build_tag 'pre'.freeze do |pre|
39
+ pre << build_tag('code'.freeze, attr){ |code| code << children_html }
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end