loincloth 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +83 -0
- data/Rakefile +18 -0
- data/VERSION +1 -0
- data/lib/loincloth.rb +20 -0
- data/lib/loincloth/block.rb +106 -0
- data/lib/loincloth/block_parser.rb +32 -0
- data/loincloth.gemspec +62 -0
- data/run_tests.rb +4 -0
- data/test/helper.rb +5 -0
- data/test/loincloth/block/emphasize.rb +34 -0
- data/test/loincloth/block/imaginize.rb +35 -0
- data/test/loincloth/block/is_h1.rb +41 -0
- data/test/loincloth/block/is_h2.rb +41 -0
- data/test/loincloth/block/is_list.rb +38 -0
- data/test/loincloth/block/is_paragraph.rb +0 -0
- data/test/loincloth/block/link.rb +35 -0
- data/test/loincloth/block/process.rb +42 -0
- data/test/loincloth/block/strongize.rb +34 -0
- data/test/loincloth/block/to_h1.rb +30 -0
- data/test/loincloth/block/to_h2.rb +30 -0
- data/test/loincloth/block/to_list.rb +31 -0
- data/test/loincloth/block/to_paragraph.rb +31 -0
- data/test/loincloth/block_parser/each_block.rb +51 -0
- data/test/loincloth/to_html.rb +65 -0
- metadata +82 -0
data/.document
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Enrique García Cota
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
loincloth
|
2
|
+
=========
|
3
|
+
|
4
|
+
This gem parses a subset of MarkDown, in an inefficient way, both in terms of speed and memory. I call that subset PoloDown.
|
5
|
+
|
6
|
+
If you are thinking using this on a production environment ... well, I admire you. But I really think you should give the proper-MarkDown-parsing gems (Maruku, BlueCloth, etc) a look first.
|
7
|
+
|
8
|
+
Also, going to the doctor would not hurt.
|
9
|
+
|
10
|
+
Target
|
11
|
+
------
|
12
|
+
|
13
|
+
The target is being able to convert headers (level 1 and 2 only), paragraphs, lists (unordered, one level), emphasized text & strong text (stars only), links and images (inline only).
|
14
|
+
|
15
|
+
|
16
|
+
``` markdown
|
17
|
+
A First Level Header
|
18
|
+
====================
|
19
|
+
|
20
|
+
A Second Level Header
|
21
|
+
---------------------
|
22
|
+
|
23
|
+
Now is the time for all *good* men to come to
|
24
|
+
the aid of **their** country. This is just a
|
25
|
+
regular paragraph.
|
26
|
+
|
27
|
+
* Get socks
|
28
|
+
* Get milk
|
29
|
+
* [Get firefox](http://getfirefox.com)
|
30
|
+
|
31
|
+
![my cat playing with a ball](/images/cat.jpg)
|
32
|
+
|
33
|
+
```
|
34
|
+
|
35
|
+
Should produce:
|
36
|
+
|
37
|
+
``` html
|
38
|
+
<h1>A First Level Header</h1>
|
39
|
+
|
40
|
+
<h2>A Second Level Header</h2>
|
41
|
+
|
42
|
+
<p>Now is the time for all <em>good</em> men to come to
|
43
|
+
the aid of <strong>their</strong> country. This is just a
|
44
|
+
regular paragraph.</p>
|
45
|
+
|
46
|
+
<ul>
|
47
|
+
<li>Get socks</li>
|
48
|
+
<li>Get milk</li>
|
49
|
+
<li><a href="http://getfirefox.com" title="Get firefox">Get firefox</a></li>
|
50
|
+
</ul>
|
51
|
+
|
52
|
+
<p><img src="/images/cat.jpg" alt="my cat playing with a ball" title="my cat playing with a ball" /></p>
|
53
|
+
```
|
54
|
+
|
55
|
+
Other notes:
|
56
|
+
|
57
|
+
* I'll be using UTF-8 on my tests. I can't guarantee it will handle other encodings properly.
|
58
|
+
* Line separators *must be* '\n'. Other line separators (specially if you use '\r' only) might give give you nasty surprises.
|
59
|
+
|
60
|
+
Tests
|
61
|
+
-----
|
62
|
+
|
63
|
+
This gem uses my testing gem, [assertor](https://rubygems.org/gems/assertor), for tests.
|
64
|
+
|
65
|
+
Consider that a business requirement. Sorry.
|
66
|
+
|
67
|
+
Contributing to loincloth
|
68
|
+
-------------------------
|
69
|
+
|
70
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
71
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
72
|
+
* Fork the project
|
73
|
+
* Start a feature/bugfix branch
|
74
|
+
* Commit and push until you are happy with your contribution
|
75
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
76
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
77
|
+
|
78
|
+
Copyright
|
79
|
+
---------
|
80
|
+
|
81
|
+
Copyright (c) 2011 Enrique García Cota. See LICENSE.txt for
|
82
|
+
further details.
|
83
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'jeweler'
|
5
|
+
Jeweler::Tasks.new do |gem|
|
6
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
7
|
+
gem.name = "loincloth"
|
8
|
+
gem.homepage = "http://github.com/kikito/loincloth"
|
9
|
+
gem.license = "MIT"
|
10
|
+
gem.summary = %Q{Like redcloth or bluecloth, but worse}
|
11
|
+
gem.description = %Q{Have you ever wanted to parse a subset of markdown, in a very innefficient way? Well, now you can!}
|
12
|
+
gem.email = "kikito@gmail.com"
|
13
|
+
gem.authors = ["Enrique García Cota"]
|
14
|
+
# dependencies defined in Gemfile
|
15
|
+
end
|
16
|
+
Jeweler::RubygemsDotOrgTasks.new
|
17
|
+
|
18
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
data/lib/loincloth.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'loincloth/block_parser'
|
2
|
+
require 'loincloth/block'
|
3
|
+
|
4
|
+
class Loincloth
|
5
|
+
|
6
|
+
def initialize(input_stream)
|
7
|
+
input_stream = StringIO.new(input_stream) if input_stream.is_a? String
|
8
|
+
@parser = BlockParser.new(input_stream)
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_html(stream=nil)
|
12
|
+
output_stream = stream.nil? ? StringIO.new : stream
|
13
|
+
@parser.each_block do |b|
|
14
|
+
b.process
|
15
|
+
output_stream << "\n" << b << "\n"
|
16
|
+
end
|
17
|
+
return output_stream.string if stream.nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
class Loincloth
|
2
|
+
|
3
|
+
class Block < String
|
4
|
+
|
5
|
+
def process
|
6
|
+
to_h1
|
7
|
+
to_h2
|
8
|
+
to_list
|
9
|
+
to_paragraph
|
10
|
+
strongize
|
11
|
+
emphasize
|
12
|
+
imaginize
|
13
|
+
link
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_h1
|
17
|
+
replace "<h1>#{h1_text}</h1>" if is_h1?
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_h2
|
21
|
+
replace "<h2>#{h2_text}</h2>" if is_h2?
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_list
|
25
|
+
replace "<ul>\n#{list_items_text}\n</ul>" if is_list?
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_paragraph
|
29
|
+
replace "<p>#{self}</p>" if is_paragraph?
|
30
|
+
end
|
31
|
+
|
32
|
+
def link
|
33
|
+
gsub! LINK do |s|
|
34
|
+
"<a href=\"#{$2}\" title=\"#{$1}\">#{$1}</a>"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def imaginize
|
39
|
+
gsub! IMAGE do |s|
|
40
|
+
"<img src=\"#{$2}\" alt=\"#{$1}\" title=\"#{$1}\" />"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def emphasize
|
45
|
+
gsub! EMPHASIS do |s|
|
46
|
+
"<em>#{$1}</em>"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def strongize
|
51
|
+
gsub! STRONG do |s|
|
52
|
+
"<strong>#{$1}</strong>"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def is_h1?
|
57
|
+
h1_text
|
58
|
+
end
|
59
|
+
|
60
|
+
def is_h2?
|
61
|
+
h2_text
|
62
|
+
end
|
63
|
+
|
64
|
+
def is_list?
|
65
|
+
list_text
|
66
|
+
end
|
67
|
+
|
68
|
+
def is_paragraph?
|
69
|
+
!is_h1? && !is_h2? && !is_list?
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
H1_BLOCK = /\A(.+)\n=+\z/m
|
75
|
+
H2_BLOCK = /\A(.+)\n-+\z/m
|
76
|
+
LIST_BLOCK = /\A\* (.+)\z/m
|
77
|
+
LI_SEPARATOR = /\n\* /
|
78
|
+
LINK = /\[(.*?)\]\((.*?)\)/m
|
79
|
+
IMAGE = /!\[(.*?)\]\((.*?)\)/m
|
80
|
+
EMPHASIS = /\*(.+?)\*/m
|
81
|
+
STRONG = /\*\*(.+?)\*\*/m
|
82
|
+
HTML_LI_SEPARATOR = "</li>\n <li>"
|
83
|
+
|
84
|
+
def h1_text
|
85
|
+
@h1_text ||= self[H1_BLOCK, 1]
|
86
|
+
end
|
87
|
+
|
88
|
+
def h2_text
|
89
|
+
@h2_text ||= self[H2_BLOCK, 1]
|
90
|
+
end
|
91
|
+
|
92
|
+
def list_text
|
93
|
+
@list_text ||= self[LIST_BLOCK, 1]
|
94
|
+
end
|
95
|
+
|
96
|
+
def list_items_text
|
97
|
+
" <li>#{list_items.join HTML_LI_SEPARATOR}</li>"
|
98
|
+
end
|
99
|
+
|
100
|
+
def list_items
|
101
|
+
list_text.split LI_SEPARATOR
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Loincloth
|
2
|
+
class BlockParser
|
3
|
+
def initialize(stream)
|
4
|
+
@stream = stream
|
5
|
+
end
|
6
|
+
def each_block(&action)
|
7
|
+
buffer = []
|
8
|
+
@stream.each{ |line|
|
9
|
+
if is_block_separator(line)
|
10
|
+
do_action(action, buffer)
|
11
|
+
buffer = []
|
12
|
+
else
|
13
|
+
buffer << line.chomp
|
14
|
+
end
|
15
|
+
}
|
16
|
+
do_action(action, buffer)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
BLOCK_SEPARATOR = /\A\n+\z/
|
22
|
+
|
23
|
+
def is_block_separator(line)
|
24
|
+
line =~ BLOCK_SEPARATOR
|
25
|
+
end
|
26
|
+
|
27
|
+
def do_action(action, buffer)
|
28
|
+
action.call(Block.new(buffer.join("\n"))) unless buffer.empty?
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
data/loincloth.gemspec
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{loincloth}
|
8
|
+
s.version = "1.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Enrique García Cota"]
|
12
|
+
s.date = %q{2011-06-10}
|
13
|
+
s.description = %q{Have you ever wanted to parse a subset of markdown, in a very innefficient way? Well, now you can!}
|
14
|
+
s.email = %q{kikito@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.markdown"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"LICENSE.txt",
|
22
|
+
"README.markdown",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"lib/loincloth.rb",
|
26
|
+
"lib/loincloth/block.rb",
|
27
|
+
"lib/loincloth/block_parser.rb",
|
28
|
+
"loincloth.gemspec",
|
29
|
+
"run_tests.rb",
|
30
|
+
"test/helper.rb",
|
31
|
+
"test/loincloth/block/emphasize.rb",
|
32
|
+
"test/loincloth/block/imaginize.rb",
|
33
|
+
"test/loincloth/block/is_h1.rb",
|
34
|
+
"test/loincloth/block/is_h2.rb",
|
35
|
+
"test/loincloth/block/is_list.rb",
|
36
|
+
"test/loincloth/block/is_paragraph.rb",
|
37
|
+
"test/loincloth/block/link.rb",
|
38
|
+
"test/loincloth/block/process.rb",
|
39
|
+
"test/loincloth/block/strongize.rb",
|
40
|
+
"test/loincloth/block/to_h1.rb",
|
41
|
+
"test/loincloth/block/to_h2.rb",
|
42
|
+
"test/loincloth/block/to_list.rb",
|
43
|
+
"test/loincloth/block/to_paragraph.rb",
|
44
|
+
"test/loincloth/block_parser/each_block.rb",
|
45
|
+
"test/loincloth/to_html.rb"
|
46
|
+
]
|
47
|
+
s.homepage = %q{http://github.com/kikito/loincloth}
|
48
|
+
s.licenses = ["MIT"]
|
49
|
+
s.require_paths = ["lib"]
|
50
|
+
s.rubygems_version = %q{1.6.2}
|
51
|
+
s.summary = %q{Like redcloth or bluecloth, but worse}
|
52
|
+
|
53
|
+
if s.respond_to? :specification_version then
|
54
|
+
s.specification_version = 3
|
55
|
+
|
56
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
57
|
+
else
|
58
|
+
end
|
59
|
+
else
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
data/run_tests.rb
ADDED
data/test/helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
module Block
|
6
|
+
class Emphasize < Assertor::Case
|
7
|
+
def should_not_transform_regular_text
|
8
|
+
should_convert "hello", "hello"
|
9
|
+
end
|
10
|
+
|
11
|
+
def should_transform_star_text_star_into_emphasized_html
|
12
|
+
should_convert "hello *this* rules", "hello <em>this</em> rules"
|
13
|
+
end
|
14
|
+
|
15
|
+
def should_not_transform_star_text_with_spaces_star_into_emphasized_html
|
16
|
+
should_convert "hello *this too* rules", "hello <em>this too</em> rules"
|
17
|
+
end
|
18
|
+
|
19
|
+
def should_work_with_multiple_words
|
20
|
+
should_convert "*hello*, you *handsome*", "<em>hello</em>, you <em>handsome</em>"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def should_convert(source, expectation)
|
26
|
+
block = ::Loincloth::Block.new source
|
27
|
+
block.emphasize
|
28
|
+
assert_equals(block, expectation)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
module Block
|
6
|
+
class Imaginize < Assertor::Case
|
7
|
+
|
8
|
+
def should_leave_regular_text_untouched
|
9
|
+
should_convert "hello", "hello"
|
10
|
+
end
|
11
|
+
|
12
|
+
def should_convert_regular_images
|
13
|
+
should_convert "![an image](/images/cat.jpg)", "<img src=\"/images/cat.jpg\" alt=\"an image\" title=\"an image\" />"
|
14
|
+
end
|
15
|
+
|
16
|
+
def should_convert_regular_images_inside_text
|
17
|
+
should_convert "this is an image ![an image](/image/cat.jpg) inside text", "this is an image <img src=\"/image/cat.jpg\" alt=\"an image\" title=\"an image\" /> inside text"
|
18
|
+
end
|
19
|
+
|
20
|
+
def should_convert_multiple_links_inside_text
|
21
|
+
should_convert "this is an image ![an image](/images/cat.jpg) and another ![another image](/images/dog.jpg) inside text", "this is an image <img src=\"/images/cat.jpg\" alt=\"an image\" title=\"an image\" /> and another <img src=\"/images/dog.jpg\" alt=\"another image\" title=\"another image\" /> inside text"
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def should_convert(source, expectation)
|
27
|
+
block = ::Loincloth::Block.new source
|
28
|
+
block.imaginize
|
29
|
+
assert_equals(block, expectation)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
module Block
|
6
|
+
class IsH1 < Assertor::Case
|
7
|
+
def should_return_true_if_last_line_is_made_out_of_3_equal_signs
|
8
|
+
should_return_true_on "hello\ncool\n==="
|
9
|
+
end
|
10
|
+
|
11
|
+
def should_return_true_if_last_line_is_made_out_of_2_equal_signs
|
12
|
+
should_return_true_on "hello\ncool\n=="
|
13
|
+
end
|
14
|
+
|
15
|
+
def should_return_false_if_last_line_contains_no_equal_signs
|
16
|
+
should_return_false_on "hello\ncool\n=a=="
|
17
|
+
end
|
18
|
+
|
19
|
+
def should_return_false_if_block_contains_just_one_line
|
20
|
+
should_return_false_on "hello"
|
21
|
+
end
|
22
|
+
|
23
|
+
def should_return_false_if_block_contains_just_one_line_even_made_of_equal_signs
|
24
|
+
should_return_false_on "==="
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def should_return_true_on(text)
|
30
|
+
block = ::Loincloth::Block.new text
|
31
|
+
assert(block.is_h1?)
|
32
|
+
end
|
33
|
+
|
34
|
+
def should_return_false_on(text)
|
35
|
+
block = ::Loincloth::Block.new text
|
36
|
+
assert_not(block.is_h1?)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
module Block
|
6
|
+
class IsH2 < Assertor::Case
|
7
|
+
def should_return_true_if_last_line_is_made_out_of_3_minus_signs
|
8
|
+
should_return_true_on "hello\ncool\n---"
|
9
|
+
end
|
10
|
+
|
11
|
+
def should_return_true_if_last_line_is_made_out_of_2_minus_signs
|
12
|
+
should_return_true_on "hello\ncool\n--"
|
13
|
+
end
|
14
|
+
|
15
|
+
def should_return_false_if_last_line_contains_no_minus_signs
|
16
|
+
should_return_false_on "hello\ncool\n-a--"
|
17
|
+
end
|
18
|
+
|
19
|
+
def should_return_false_if_block_contains_just_one_line
|
20
|
+
should_return_false_on "hello"
|
21
|
+
end
|
22
|
+
|
23
|
+
def should_return_false_if_block_contains_just_one_line_even_made_of_minus_signs
|
24
|
+
should_return_false_on "---"
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def should_return_true_on(text)
|
30
|
+
block = ::Loincloth::Block.new text
|
31
|
+
assert(block.is_h2?)
|
32
|
+
end
|
33
|
+
|
34
|
+
def should_return_false_on(text)
|
35
|
+
block = ::Loincloth::Block.new text
|
36
|
+
assert_not(block.is_h2?)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
module Block
|
6
|
+
class IsParagraph < Assertor::Case
|
7
|
+
def should_return_true_on_regular_text
|
8
|
+
should_return_true_on "hello"
|
9
|
+
end
|
10
|
+
|
11
|
+
def should_return_true_on_h1_text
|
12
|
+
should_return_false_on "hello\n==="
|
13
|
+
end
|
14
|
+
|
15
|
+
def should_return_true_on_h2_text
|
16
|
+
should_return_false_on "hello\n---"
|
17
|
+
end
|
18
|
+
|
19
|
+
def should_return_true_on_list_text
|
20
|
+
should_return_false_on "* hello"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def should_return_true_on(text)
|
26
|
+
block = ::Loincloth::Block.new text
|
27
|
+
assert(block.is_paragraph?)
|
28
|
+
end
|
29
|
+
|
30
|
+
def should_return_false_on(text)
|
31
|
+
block = ::Loincloth::Block.new text
|
32
|
+
assert_not(block.is_paragraph?)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
File without changes
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
module Block
|
6
|
+
class Link < Assertor::Case
|
7
|
+
|
8
|
+
def should_leave_regular_text_untouched
|
9
|
+
should_convert "hello", "hello"
|
10
|
+
end
|
11
|
+
|
12
|
+
def should_convert_regular_links
|
13
|
+
should_convert "[link to google](http://www.google.com)", "<a href=\"http://www.google.com\" title=\"link to google\">link to google</a>"
|
14
|
+
end
|
15
|
+
|
16
|
+
def should_convert_regular_links_inside_text
|
17
|
+
should_convert "this is a [link to google](http://www.google.com) inside text", "this is a <a href=\"http://www.google.com\" title=\"link to google\">link to google</a> inside text"
|
18
|
+
end
|
19
|
+
|
20
|
+
def should_convert_multiple_links_inside_text
|
21
|
+
should_convert "this is a [link to google](http://www.google.com) and a [link to github](http://www.github.com) inside text", "this is a <a href=\"http://www.google.com\" title=\"link to google\">link to google</a> and a <a href=\"http://www.github.com\" title=\"link to github\">link to github</a> inside text"
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def should_convert(source, expectation)
|
27
|
+
block = ::Loincloth::Block.new source
|
28
|
+
block.link
|
29
|
+
assert_equals(block, expectation)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
module Block
|
6
|
+
class Process < Assertor::Case
|
7
|
+
|
8
|
+
def should_process_h1
|
9
|
+
should_convert "Hello\n===", "<h1>Hello</h1>"
|
10
|
+
end
|
11
|
+
def should_process_h2
|
12
|
+
should_convert "Hello\n---", "<h2>Hello</h2>"
|
13
|
+
end
|
14
|
+
def should_process_lists
|
15
|
+
should_convert "* One\n* Two\n* Three", "<ul>\n <li>One</li>\n <li>Two</li>\n <li>Three</li>\n</ul>"
|
16
|
+
end
|
17
|
+
def should_process_paragraphs
|
18
|
+
should_convert "hello", "<p>hello</p>"
|
19
|
+
end
|
20
|
+
def should_process_strong_on_h1
|
21
|
+
should_convert "I say **hello**\n===", "<h1>I say <strong>hello</strong></h1>"
|
22
|
+
end
|
23
|
+
def should_process_emphasis_on_lists
|
24
|
+
should_convert "* *hello*", "<ul>\n <li><em>hello</em></li>\n</ul>"
|
25
|
+
end
|
26
|
+
def should_process_images_and_links
|
27
|
+
should_convert "An image: ![image](/images/image.jpg) and a [link](http://google.com).", "<p>An image: <img src=\"/images/image.jpg\" alt=\"image\" title=\"image\" /> and a <a href=\"http://google.com\" title=\"link\">link</a>.</p>"
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def should_convert(source, expectation)
|
34
|
+
block = ::Loincloth::Block.new source
|
35
|
+
block.process
|
36
|
+
assert_equals(block, expectation)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
module Block
|
6
|
+
class Strongize < Assertor::Case
|
7
|
+
def should_not_transform_regular_text
|
8
|
+
should_convert "hello", "hello"
|
9
|
+
end
|
10
|
+
|
11
|
+
def should_transform_star_text_star_into_emphasized_html
|
12
|
+
should_convert "hello **this** rules", "hello <strong>this</strong> rules"
|
13
|
+
end
|
14
|
+
|
15
|
+
def should_not_transform_star_text_with_spaces_star_into_emphasized_html
|
16
|
+
should_convert "hello **this too** rules", "hello <strong>this too</strong> rules"
|
17
|
+
end
|
18
|
+
|
19
|
+
def should_work_with_multiple_words
|
20
|
+
should_convert "**hello**, you **handsome**", "<strong>hello</strong>, you <strong>handsome</strong>"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def should_convert(source, expectation)
|
26
|
+
block = ::Loincloth::Block.new source
|
27
|
+
block.strongize
|
28
|
+
assert_equals(block, expectation)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
module Block
|
6
|
+
class ToH1 < Assertor::Case
|
7
|
+
def should_return_convert_headers_with_4_equals
|
8
|
+
should_convert "hello\n====", "<h1>hello</h1>"
|
9
|
+
end
|
10
|
+
|
11
|
+
def should_return_convert_regular_with_2_equals
|
12
|
+
should_convert "hello\n==", "<h1>hello</h1>"
|
13
|
+
end
|
14
|
+
|
15
|
+
def should_leave_non_headers_untouched
|
16
|
+
should_convert "hello", "hello"
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def should_convert(source, expectation)
|
22
|
+
block = ::Loincloth::Block.new source
|
23
|
+
block.to_h1
|
24
|
+
assert_equals(block, expectation)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
module Block
|
6
|
+
class ToH2 < Assertor::Case
|
7
|
+
def should_return_convert_headers_with_4_minus
|
8
|
+
should_convert "hello\n----", "<h2>hello</h2>"
|
9
|
+
end
|
10
|
+
|
11
|
+
def should_return_convert_regular_with_2_minus
|
12
|
+
should_convert "hello\n--", "<h2>hello</h2>"
|
13
|
+
end
|
14
|
+
|
15
|
+
def should_leave_non_headers_untouched
|
16
|
+
should_convert "hello", "hello"
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def should_convert(source, expectation)
|
22
|
+
block = ::Loincloth::Block.new source
|
23
|
+
block.to_h2
|
24
|
+
assert_equals(block, expectation)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
module Block
|
6
|
+
class ToList < Assertor::Case
|
7
|
+
def should_convert_to_list_a_one_line_list
|
8
|
+
should_convert "* hello", "<ul>\n <li>hello</li>\n</ul>"
|
9
|
+
end
|
10
|
+
def should_do_nothing_with_regular_text
|
11
|
+
should_convert "hello", "hello"
|
12
|
+
end
|
13
|
+
def should_convert_to_2_li_list_with_two_stars
|
14
|
+
should_convert "* hello\n* bye", "<ul>\n <li>hello</li>\n <li>bye</li>\n</ul>"
|
15
|
+
end
|
16
|
+
def should_convert_to_2_li_list_with_stars_in_the_middle
|
17
|
+
should_convert "* hello * man\n * how \n* are \n you *", "<ul>\n <li>hello * man\n * how </li>\n <li>are \n you *</li>\n</ul>"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def should_convert(source, expectation)
|
23
|
+
block = ::Loincloth::Block.new source
|
24
|
+
block.to_list
|
25
|
+
assert_equals(block, expectation)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
module Block
|
6
|
+
class ToParagraph < Assertor::Case
|
7
|
+
def should_convert_regular_text_to_paragraph
|
8
|
+
should_convert "hello", "<p>hello</p>"
|
9
|
+
end
|
10
|
+
def should_not_convert_h1_text
|
11
|
+
should_convert "hello\n===", "hello\n==="
|
12
|
+
end
|
13
|
+
def should_not_convert_h2_text
|
14
|
+
should_convert "hello\n---", "hello\n---"
|
15
|
+
end
|
16
|
+
def should_not_convert_list_text
|
17
|
+
should_convert "* hello \n* man", "* hello \n* man"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def should_convert(source, expectation)
|
23
|
+
block = ::Loincloth::Block.new source
|
24
|
+
block.to_paragraph
|
25
|
+
assert_equals(block, expectation)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Test
|
5
|
+
module LoinclothTests
|
6
|
+
module BlockParser
|
7
|
+
|
8
|
+
class EachBlock < Assertor::Case
|
9
|
+
|
10
|
+
BLOCKS = ['first', 'second', 'third']
|
11
|
+
|
12
|
+
def should_return_empty_array_with_empty_string
|
13
|
+
should_split "", []
|
14
|
+
end
|
15
|
+
|
16
|
+
def should_return_empty_array_with_newline_string
|
17
|
+
should_split "\n", []
|
18
|
+
end
|
19
|
+
|
20
|
+
def should_separate_by_nn
|
21
|
+
should_split BLOCKS.join "\n\n"
|
22
|
+
end
|
23
|
+
|
24
|
+
def should_separate_by_nnn
|
25
|
+
should_split BLOCKS.join "\n\n\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
def should_not_separate_by_n
|
29
|
+
should_split BLOCKS.join("\n"), ["first\nsecond\nthird"]
|
30
|
+
end
|
31
|
+
|
32
|
+
def should_separate_appropiately
|
33
|
+
should_split "first\nsecond\n\nthird", ["first\nsecond", "third"]
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def should_split(text, target=BLOCKS)
|
39
|
+
parser = ::Loincloth::BlockParser.new(StringIO.new(text))
|
40
|
+
blocks = []
|
41
|
+
parser.each_block{|block| blocks << block }
|
42
|
+
blocks.each{|block| assert(block.is_a? ::Loincloth::Block)}
|
43
|
+
assert_equals blocks, target
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Test
|
4
|
+
module Loincloth
|
5
|
+
class ToHtml < Assertor::Case
|
6
|
+
INPUT = <<-eos
|
7
|
+
A First Level Header
|
8
|
+
====================
|
9
|
+
|
10
|
+
A Second Level Header
|
11
|
+
---------------------
|
12
|
+
|
13
|
+
Now is the time for all *good* men to come to
|
14
|
+
the aid of **their** country. This is just a
|
15
|
+
regular paragraph.
|
16
|
+
|
17
|
+
* Get socks
|
18
|
+
* Get milk
|
19
|
+
* [Get firefox](http://getfirefox.com)
|
20
|
+
|
21
|
+
![my cat playing with a ball](/images/cat.jpg)
|
22
|
+
eos
|
23
|
+
|
24
|
+
OUTPUT = <<-eos
|
25
|
+
|
26
|
+
<h1>A First Level Header</h1>
|
27
|
+
|
28
|
+
<h2>A Second Level Header</h2>
|
29
|
+
|
30
|
+
<p>Now is the time for all <em>good</em> men to come to
|
31
|
+
the aid of <strong>their</strong> country. This is just a
|
32
|
+
regular paragraph.</p>
|
33
|
+
|
34
|
+
<ul>
|
35
|
+
<li>Get socks</li>
|
36
|
+
<li>Get milk</li>
|
37
|
+
<li><a href="http://getfirefox.com" title="Get firefox">Get firefox</a></li>
|
38
|
+
</ul>
|
39
|
+
|
40
|
+
<p><img src="/images/cat.jpg" alt="my cat playing with a ball" title="my cat playing with a ball" /></p>
|
41
|
+
eos
|
42
|
+
|
43
|
+
def works_with_stream_stream
|
44
|
+
output = StringIO.new
|
45
|
+
::Loincloth.new(StringIO.new(INPUT)).to_html output
|
46
|
+
assert_equals(output.string, OUTPUT)
|
47
|
+
end
|
48
|
+
|
49
|
+
def works_with_string_string
|
50
|
+
assert_equals(::Loincloth.new(INPUT).to_html, OUTPUT)
|
51
|
+
end
|
52
|
+
|
53
|
+
def works_with_string_stream
|
54
|
+
output = StringIO.new
|
55
|
+
::Loincloth.new(INPUT).to_html output
|
56
|
+
assert_equals(output.string, OUTPUT)
|
57
|
+
end
|
58
|
+
|
59
|
+
def works_with_stream_string
|
60
|
+
assert_equals(::Loincloth.new(StringIO.new(INPUT)).to_html, OUTPUT)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: loincloth
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 1.0.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- "Enrique Garc\xC3\xADa Cota"
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-06-10 00:00:00 +02:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: Have you ever wanted to parse a subset of markdown, in a very innefficient way? Well, now you can!
|
18
|
+
email: kikito@gmail.com
|
19
|
+
executables: []
|
20
|
+
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files:
|
24
|
+
- LICENSE.txt
|
25
|
+
- README.markdown
|
26
|
+
files:
|
27
|
+
- .document
|
28
|
+
- LICENSE.txt
|
29
|
+
- README.markdown
|
30
|
+
- Rakefile
|
31
|
+
- VERSION
|
32
|
+
- lib/loincloth.rb
|
33
|
+
- lib/loincloth/block.rb
|
34
|
+
- lib/loincloth/block_parser.rb
|
35
|
+
- loincloth.gemspec
|
36
|
+
- run_tests.rb
|
37
|
+
- test/helper.rb
|
38
|
+
- test/loincloth/block/emphasize.rb
|
39
|
+
- test/loincloth/block/imaginize.rb
|
40
|
+
- test/loincloth/block/is_h1.rb
|
41
|
+
- test/loincloth/block/is_h2.rb
|
42
|
+
- test/loincloth/block/is_list.rb
|
43
|
+
- test/loincloth/block/is_paragraph.rb
|
44
|
+
- test/loincloth/block/link.rb
|
45
|
+
- test/loincloth/block/process.rb
|
46
|
+
- test/loincloth/block/strongize.rb
|
47
|
+
- test/loincloth/block/to_h1.rb
|
48
|
+
- test/loincloth/block/to_h2.rb
|
49
|
+
- test/loincloth/block/to_list.rb
|
50
|
+
- test/loincloth/block/to_paragraph.rb
|
51
|
+
- test/loincloth/block_parser/each_block.rb
|
52
|
+
- test/loincloth/to_html.rb
|
53
|
+
has_rdoc: true
|
54
|
+
homepage: http://github.com/kikito/loincloth
|
55
|
+
licenses:
|
56
|
+
- MIT
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.6.2
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: Like redcloth or bluecloth, but worse
|
81
|
+
test_files: []
|
82
|
+
|