guileless 0.1.0 → 0.1.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.
- checksums.yaml +5 -13
- data/Gemfile.lock +1 -0
- data/README.md +19 -2
- data/guileless.gemspec +1 -3
- data/lib/guileless/parse_methods.rb +30 -31
- data/lib/guileless/parser.rb +7 -1
- data/lib/guileless/version.rb +1 -1
- data/spec/guileless_spec.rb +7 -0
- metadata +8 -9
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YTcxMzkzNGIwODYxZTkzZWRiMDdkY2Q4ZTY3NWMwYTZiMjY5MjFjOQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d117a31360e13a08ef5a01518c0240018b891c35
|
4
|
+
data.tar.gz: da16fe450906543184362d9978800917dc3b1107
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
YmIwMWI1MzY4ZGRkMDE5ZDE4ZTQwNDgwYWFlZDFiMTVlZThiZTk1ODhjOTUw
|
11
|
-
NTdkZmJlMjY4MTJhMDE5NjdkYTM0MzExZTVhMGEzZWMyNTQzNDQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YzgwYWY1ZWY2M2U2OTBmYTkyNTI5NTUwMzk0MDAwMTNmM2Q2ZDViOThjNDlj
|
14
|
-
YTU3YjNiYWJiODAxNjk5ZjBhZDVhZjg1NjgxMDhjZjAxYmQ5MDZkZjVlN2Q4
|
15
|
-
NDIxYmRmMTY3MjIyZjVmZWIxN2RiMGQwYmRmZDQwMDg5ODA3Nzk=
|
6
|
+
metadata.gz: 6a978d321323f4eaec09533839e064c832a2ffb83c11dd173d138b7e839c7124f4d62621054595678a7171cd594a2a8e7373496c12f3f7eae0ff5a800b55c56b
|
7
|
+
data.tar.gz: bd494836464020a0af2eec465ee62fe80a93568872f16ceb0f48622ed5a904f1ce9bc827c4911a73f81073c4b2c40eb04fd7caad3bc3beaf6267aba53aa05257
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -4,14 +4,26 @@ Guileless is a naive HTML preprocessor. It does three things:
|
|
4
4
|
|
5
5
|
1. Single line breaks are converted to `<br>`
|
6
6
|
2. Several consecutive line breaks are treated as paragraphs and wrapped in `<p>`
|
7
|
-
3. Converts stray `<`, `>`, and `&`s to
|
7
|
+
3. Converts stray `<`, `>`, and `&`s to character entities.
|
8
8
|
|
9
9
|
Why is this more useful than, say, Rails' built in `simple_format`?
|
10
10
|
|
11
11
|
Well, it's actually a real (if simplistic) HTML parser. It understands nested
|
12
12
|
tags, and will happily format text nodes inside `div`s and `blockquote`s.
|
13
13
|
|
14
|
-
|
14
|
+
Valid HTML is assumed, and it doesn't do any sanitation on the input.
|
15
|
+
Anything it doesn't need to understand is simply passed through, but
|
16
|
+
mismatched or missing opening and closing tags on block level elements will break.
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
gem install guileless
|
23
|
+
|
24
|
+
or add it to your gemfile:
|
25
|
+
|
26
|
+
gem "guileless"
|
15
27
|
|
16
28
|
## Usage
|
17
29
|
|
@@ -19,6 +31,11 @@ However, it does **NOT** do any sanitation on the input.
|
|
19
31
|
Guileless.format("<div>foo</div>") # => "<div><p>foo</p></div>"
|
20
32
|
```
|
21
33
|
|
34
|
+
## Contributing
|
35
|
+
|
36
|
+
♫ Fork it, use it, break it, fix it,
|
37
|
+
branch it, push it, pull request it.
|
38
|
+
|
22
39
|
## License
|
23
40
|
|
24
41
|
Copyright (c) 2013 Inge Jørgensen
|
data/guileless.gemspec
CHANGED
@@ -6,12 +6,11 @@ require "guileless/version"
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = 'guileless'
|
8
8
|
s.version = Guileless::VERSION
|
9
|
-
s.date = '
|
9
|
+
s.date = '2014-05-21'
|
10
10
|
s.summary = "Naive HTML preprocessor"
|
11
11
|
s.description = "Naive HTML preprocessor"
|
12
12
|
s.authors = ["Inge Jørgensen"]
|
13
13
|
s.email = 'inge@elektronaut.no'
|
14
|
-
s.files = ["lib/hola.rb"]
|
15
14
|
s.homepage = 'http://github.com/elektronaut/guileless'
|
16
15
|
s.license = 'MIT'
|
17
16
|
s.required_ruby_version = Gem::Requirement.new(">= 1.9.2")
|
@@ -20,5 +19,4 @@ Gem::Specification.new do |s|
|
|
20
19
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
20
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
21
|
s.require_paths = ["lib"]
|
23
|
-
|
24
22
|
end
|
@@ -1,6 +1,18 @@
|
|
1
1
|
module Guileless
|
2
2
|
module ParseMethods
|
3
3
|
|
4
|
+
def escape_ampersand
|
5
|
+
value = stream.peek?(/[\w\d]+;/) ? "&" : "&"
|
6
|
+
@char_count += value.length
|
7
|
+
value
|
8
|
+
end
|
9
|
+
|
10
|
+
def start_tag
|
11
|
+
if stream.peek?(block_level_tags) || stream.peek?(closing(block_level_tags))
|
12
|
+
flush_buffer
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
4
16
|
def parse_attribute_name(char)
|
5
17
|
case
|
6
18
|
when char !=~ /[\w\-]/
|
@@ -63,26 +75,19 @@ module Guileless
|
|
63
75
|
end
|
64
76
|
end
|
65
77
|
|
66
|
-
def parse_tag_name(char)
|
78
|
+
def parse_tag_name(char, next_state=:tag)
|
67
79
|
case
|
68
80
|
when char =~ /\w/
|
69
81
|
@tag_name += char
|
70
82
|
char
|
71
83
|
else
|
72
84
|
stream.reinject char
|
73
|
-
[false,
|
85
|
+
[false, next_state]
|
74
86
|
end
|
75
87
|
end
|
76
88
|
|
77
89
|
def parse_closing_tag_name(char)
|
78
|
-
|
79
|
-
when char =~ /\w/
|
80
|
-
@tag_name += char
|
81
|
-
char
|
82
|
-
else
|
83
|
-
stream.reinject char
|
84
|
-
[false, :closing_tag]
|
85
|
-
end
|
90
|
+
parse_tag_name(char, :closing_tag)
|
86
91
|
end
|
87
92
|
|
88
93
|
def parse_left_angled_quote(char)
|
@@ -93,23 +98,14 @@ module Guileless
|
|
93
98
|
stream.discard(3)
|
94
99
|
["<!--", :comment]
|
95
100
|
|
96
|
-
# Opening block tag
|
97
|
-
when stream.peek?(block_level_tags)
|
98
|
-
flush_buffer
|
99
|
-
[char, :tag_name]
|
100
|
-
|
101
101
|
# Opening tag
|
102
102
|
when stream.peek?(html_tags)
|
103
|
+
start_tag
|
103
104
|
[char, :tag_name]
|
104
105
|
|
105
|
-
# Closing block level tag
|
106
|
-
when stream.peek?(closing(block_level_tags))
|
107
|
-
flush_buffer
|
108
|
-
stream.discard
|
109
|
-
["</", :closing_tag_name]
|
110
|
-
|
111
106
|
# Closing tag
|
112
107
|
when stream.peek?(closing(html_tags))
|
108
|
+
start_tag
|
113
109
|
stream.discard
|
114
110
|
["</", :closing_tag_name]
|
115
111
|
|
@@ -120,6 +116,16 @@ module Guileless
|
|
120
116
|
end
|
121
117
|
end
|
122
118
|
|
119
|
+
def parse_linebreak
|
120
|
+
if stream.peek?("\n")
|
121
|
+
flush_buffer
|
122
|
+
stream.strip_whitespace
|
123
|
+
false
|
124
|
+
else
|
125
|
+
"<br>"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
123
129
|
def parse_text(char)
|
124
130
|
case
|
125
131
|
|
@@ -133,19 +139,12 @@ module Guileless
|
|
133
139
|
">"
|
134
140
|
|
135
141
|
# Escape ampersands
|
136
|
-
when char == "&"
|
137
|
-
|
138
|
-
"&"
|
139
|
-
|
140
|
-
# Paragraph break
|
141
|
-
when char == "\n" && stream.peek?("\n")
|
142
|
-
flush_buffer
|
143
|
-
stream.strip_whitespace
|
144
|
-
false
|
142
|
+
when char == "&"
|
143
|
+
escape_ampersand
|
145
144
|
|
146
145
|
# Line break
|
147
146
|
when char == "\n"
|
148
|
-
|
147
|
+
parse_linebreak
|
149
148
|
|
150
149
|
when char !=~ /\s/
|
151
150
|
@char_count += 1
|
data/lib/guileless/parser.rb
CHANGED
@@ -84,10 +84,16 @@ module Guileless
|
|
84
84
|
@tag_name = ""
|
85
85
|
end
|
86
86
|
|
87
|
+
def filtered_input
|
88
|
+
# Ignoring carriage return should be fine for now,
|
89
|
+
# the output doesn't contain newlines.
|
90
|
+
input.gsub(/\r/, '')
|
91
|
+
end
|
92
|
+
|
87
93
|
def reset!
|
88
94
|
@char_count = 0
|
89
95
|
@buffer = Guileless::OutputBuffer.new
|
90
|
-
@stream = Guileless::InputStream.new(
|
96
|
+
@stream = Guileless::InputStream.new(filtered_input)
|
91
97
|
@tag_stack = []
|
92
98
|
reset_tag_name
|
93
99
|
@state = :text
|
data/lib/guileless/version.rb
CHANGED
data/spec/guileless_spec.rb
CHANGED
@@ -20,10 +20,12 @@ describe Guileless do
|
|
20
20
|
|
21
21
|
it "converts single breaks to <br>" do
|
22
22
|
Guileless.format("foo\nbar").should == "<p>foo<br>bar</p>"
|
23
|
+
Guileless.format("foo\r\nbar").should == "<p>foo<br>bar</p>"
|
23
24
|
end
|
24
25
|
|
25
26
|
it "converts double breaks to <br>" do
|
26
27
|
Guileless.format("foo\n\nbar").should == "<p>foo</p><p>bar</p>"
|
28
|
+
Guileless.format("foo\r\n\r\nbar").should == "<p>foo</p><p>bar</p>"
|
27
29
|
end
|
28
30
|
|
29
31
|
it "escapes left angled brackets" do
|
@@ -42,6 +44,11 @@ describe Guileless do
|
|
42
44
|
Guileless.format("&").should == "<p>&</p>"
|
43
45
|
end
|
44
46
|
|
47
|
+
it "doesn't escape other character entities" do
|
48
|
+
Guileless.format(" ").should == "<p> </p>"
|
49
|
+
Guileless.format("💩").should == "<p>💩</p>"
|
50
|
+
end
|
51
|
+
|
45
52
|
it "understands empty attributes" do
|
46
53
|
Guileless.format("<blockquote data-foo>stuff</blockquote>").should == "<blockquote data-foo><p>stuff</p></blockquote>"
|
47
54
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: guileless
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Inge Jørgensen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-05-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Naive HTML preprocessor
|
14
14
|
email: inge@elektronaut.no
|
@@ -16,9 +16,9 @@ executables: []
|
|
16
16
|
extensions: []
|
17
17
|
extra_rdoc_files: []
|
18
18
|
files:
|
19
|
-
- .gitignore
|
20
|
-
- .rspec
|
21
|
-
- .travis.yml
|
19
|
+
- ".gitignore"
|
20
|
+
- ".rspec"
|
21
|
+
- ".travis.yml"
|
22
22
|
- Gemfile
|
23
23
|
- Gemfile.lock
|
24
24
|
- LICENSE
|
@@ -44,21 +44,20 @@ require_paths:
|
|
44
44
|
- lib
|
45
45
|
required_ruby_version: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- -
|
47
|
+
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
49
|
version: 1.9.2
|
50
50
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
requirements: []
|
56
56
|
rubyforge_project:
|
57
|
-
rubygems_version: 2.
|
57
|
+
rubygems_version: 2.2.0
|
58
58
|
signing_key:
|
59
59
|
specification_version: 4
|
60
60
|
summary: Naive HTML preprocessor
|
61
61
|
test_files:
|
62
62
|
- spec/guileless_spec.rb
|
63
63
|
- spec/spec_helper.rb
|
64
|
-
has_rdoc:
|