aleph 0.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.
- data/Rakefile +7 -0
- data/aleph.gemspec +13 -0
- data/lib/aleph.rb +73 -0
- data/test/aleph.rb +103 -0
- data/test/binary.rb +23 -0
- data/test/simple.html +21 -0
- metadata +99 -0
data/Rakefile
ADDED
data/aleph.gemspec
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "aleph"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.summary = "Literate-programming HTML"
|
5
|
+
s.authors = ["Damian Janowski", "Michel Martens"]
|
6
|
+
s.email = ["djanowski@dimaion.com", "michel@soveran.com"]
|
7
|
+
s.homepage = "http://github.com/djanowski/aleph"
|
8
|
+
|
9
|
+
s.files = ["Rakefile", "lib/aleph.rb", "aleph.gemspec", "test/aleph.rb", "test/binary.rb", "test/simple.html"]
|
10
|
+
|
11
|
+
s.add_dependency "nokogiri", "~> 1.4"
|
12
|
+
s.add_dependency "rdiscount", "~> 1.6"
|
13
|
+
end
|
data/lib/aleph.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require "nokogiri"
|
4
|
+
require "rdiscount"
|
5
|
+
|
6
|
+
class Aleph
|
7
|
+
VERSION = "0.0.1"
|
8
|
+
|
9
|
+
def self.process(source)
|
10
|
+
new(source).process
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(source)
|
14
|
+
@source = source
|
15
|
+
|
16
|
+
@doc = Nokogiri::HTML("<meta http-equiv='content-type' content='text/html; charset=utf-8'><table class='aleph'></table>")
|
17
|
+
end
|
18
|
+
|
19
|
+
def process
|
20
|
+
comments = nil
|
21
|
+
|
22
|
+
@source.each_line do |line|
|
23
|
+
if line =~ %r{^\s*(<!--|/\*)\s*$}
|
24
|
+
comments = ""
|
25
|
+
elsif line =~ %r{^\s*(-->|\*/)\s*$}
|
26
|
+
new_row
|
27
|
+
comment(unindent(comments))
|
28
|
+
comments = nil
|
29
|
+
else
|
30
|
+
if comments
|
31
|
+
comments << line
|
32
|
+
else
|
33
|
+
code(line)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
table.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
|
43
|
+
def table
|
44
|
+
@table ||= @doc.at_xpath("//table")
|
45
|
+
end
|
46
|
+
|
47
|
+
def row
|
48
|
+
table.children.last
|
49
|
+
end
|
50
|
+
|
51
|
+
def new_row
|
52
|
+
table << "<tr><td></td><td><pre><code></code></pre></td></tr>"
|
53
|
+
end
|
54
|
+
|
55
|
+
def unindent(text)
|
56
|
+
spaces = 0
|
57
|
+
|
58
|
+
spaces = $1.size - 1 if text =~ /\A(\s+)/
|
59
|
+
|
60
|
+
lines = text.split("\n").map do |line|
|
61
|
+
line[spaces..-1]
|
62
|
+
end.join("\n")
|
63
|
+
end
|
64
|
+
|
65
|
+
def comment(text)
|
66
|
+
filtered = RDiscount.new(text.strip).to_html
|
67
|
+
row.at_xpath("./td[1]").inner_html = filtered
|
68
|
+
end
|
69
|
+
|
70
|
+
def code(text)
|
71
|
+
row.at_xpath("./td[2]/pre/code").content += text
|
72
|
+
end
|
73
|
+
end
|
data/test/aleph.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require "cutest"
|
4
|
+
require "nokogiri"
|
5
|
+
|
6
|
+
require_relative "../lib/aleph"
|
7
|
+
|
8
|
+
test "splits comments and code" do
|
9
|
+
result = Aleph.process(<<-EOS)
|
10
|
+
<!--
|
11
|
+
This is the intro
|
12
|
+
-->
|
13
|
+
|
14
|
+
<!--
|
15
|
+
Boilerplate
|
16
|
+
-->
|
17
|
+
<!DOCTYPE html>
|
18
|
+
<html>
|
19
|
+
<body>
|
20
|
+
<!--
|
21
|
+
This is the header.
|
22
|
+
|
23
|
+
We use the HTML5 element.
|
24
|
+
-->
|
25
|
+
<header>
|
26
|
+
</header>
|
27
|
+
|
28
|
+
<!--
|
29
|
+
This is the footer
|
30
|
+
-->
|
31
|
+
<footer>
|
32
|
+
</footer>
|
33
|
+
</body>
|
34
|
+
</html>
|
35
|
+
EOS
|
36
|
+
|
37
|
+
table = Nokogiri::HTML(result).at_xpath("./html/body").children.first
|
38
|
+
|
39
|
+
assert table.at("./tr[1]/td[1]").text =~ %r{This is the intro}
|
40
|
+
assert table.at("./tr[1]/td[2]/pre/code").text.strip.empty?
|
41
|
+
|
42
|
+
assert table.at("./tr[2]/td[1]/p").text =~ /Boilerplate/
|
43
|
+
assert table.at("./tr[2]/td[2]/pre/code").content =~ /<!DOCTYPE html>.*<html>.*<body>/m
|
44
|
+
|
45
|
+
assert table.at("./tr[3]/td[1]/p[1]").text =~ %r{This is the header}
|
46
|
+
assert table.at("./tr[3]/td[1]/p[2]").text =~ %r{We use the HTML5 element}
|
47
|
+
assert table.at("./tr[3]/td[2]/pre/code").content =~ /<header>.*<\/header>/m
|
48
|
+
end
|
49
|
+
|
50
|
+
test "filters comments through Markdown" do
|
51
|
+
result = Aleph.process(<<-EOS)
|
52
|
+
<!--
|
53
|
+
This is **the** intro.
|
54
|
+
|
55
|
+
Additional paragraphs here.
|
56
|
+
|
57
|
+
Aló.
|
58
|
+
-->
|
59
|
+
<!DOCTYPE html>
|
60
|
+
<html>
|
61
|
+
<body>
|
62
|
+
</body>
|
63
|
+
</html>
|
64
|
+
EOS
|
65
|
+
|
66
|
+
table = Nokogiri::HTML(result).at_xpath("./html/body").children.first
|
67
|
+
|
68
|
+
assert table.at("./tr[1]/td[1]/p[1]").inner_html =~ %r{This is <strong>the</strong> intro}
|
69
|
+
assert table.at("./tr[1]/td[1]/p[2]").inner_html =~ %r{Additional paragraphs here}
|
70
|
+
assert table.at("./tr[1]/td[1]/p[3]").inner_html =~ %r{Aló}
|
71
|
+
end
|
72
|
+
|
73
|
+
test "embedded JavaScript" do
|
74
|
+
result = Aleph.process(<<-EOS)
|
75
|
+
<!--
|
76
|
+
This is the intro
|
77
|
+
-->
|
78
|
+
<!DOCTYPE html>
|
79
|
+
<html>
|
80
|
+
<body>
|
81
|
+
<!--
|
82
|
+
This is the header.
|
83
|
+
-->
|
84
|
+
<header>
|
85
|
+
</header>
|
86
|
+
|
87
|
+
<script type="text/javascript">
|
88
|
+
/*
|
89
|
+
Initialize everything.
|
90
|
+
*/
|
91
|
+
function initialize() {
|
92
|
+
}
|
93
|
+
</script>
|
94
|
+
</body>
|
95
|
+
</html>
|
96
|
+
EOS
|
97
|
+
|
98
|
+
table = Nokogiri::HTML(result).at_xpath("./html/body").children.first
|
99
|
+
|
100
|
+
assert table.at("./tr[1]/td[1]").text =~ %r{This is the intro}
|
101
|
+
|
102
|
+
assert table.at("./tr[3]/td[1]/p[1]").text =~ %r{Initialize everything}
|
103
|
+
end
|
data/test/binary.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "cutest"
|
2
|
+
|
3
|
+
require_relative "../lib/aleph"
|
4
|
+
|
5
|
+
BINARY = File.expand_path("../bin/aleph", File.dirname(__FILE__))
|
6
|
+
|
7
|
+
test "parses the given file" do
|
8
|
+
result = `ruby #{BINARY} test/simple.html`
|
9
|
+
|
10
|
+
assert !result.empty?
|
11
|
+
|
12
|
+
table = Nokogiri::HTML(result).at_xpath("./html/body").children.first
|
13
|
+
|
14
|
+
assert table.at("./tr[1]/td[1]/h1").text =~ %r{Welcome to Aleph}
|
15
|
+
assert table.at("./tr[1]/td[1]/p").text =~ %r{This is the introduction}
|
16
|
+
assert table.at("./tr[1]/td[2]/pre/code").text.strip.empty?
|
17
|
+
|
18
|
+
assert_equal "", table.at("./tr[2]/td[1]").text.strip
|
19
|
+
assert table.at("./tr[2]/td[2]/pre/code").content =~ /<!DOCTYPE html>.*<html>.*<body>/m
|
20
|
+
|
21
|
+
assert table.at("./tr[3]/td[1]/p").content =~ %r{We'll use the <header> element for the website's header.}
|
22
|
+
assert table.at("./tr[3]/td[2]/pre/code").content =~ %r{<header>.*Welcome.*</header>}m
|
23
|
+
end
|
data/test/simple.html
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
<!--
|
2
|
+
|
3
|
+
Welcome to Aleph
|
4
|
+
===
|
5
|
+
|
6
|
+
This is the introduction.
|
7
|
+
|
8
|
+
-->
|
9
|
+
<!--
|
10
|
+
-->
|
11
|
+
<!DOCTYPE html>
|
12
|
+
<html>
|
13
|
+
<body>
|
14
|
+
<!--
|
15
|
+
We'll use the <header> element for the website's header.
|
16
|
+
-->
|
17
|
+
<header>
|
18
|
+
Welcome
|
19
|
+
</header>
|
20
|
+
</body>
|
21
|
+
</html>
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aleph
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Damian Janowski
|
13
|
+
- Michel Martens
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-12-30 00:00:00 -03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: nokogiri
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
segments:
|
30
|
+
- 1
|
31
|
+
- 4
|
32
|
+
version: "1.4"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rdiscount
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 1
|
45
|
+
- 6
|
46
|
+
version: "1.6"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
description:
|
50
|
+
email:
|
51
|
+
- djanowski@dimaion.com
|
52
|
+
- michel@soveran.com
|
53
|
+
executables: []
|
54
|
+
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
extra_rdoc_files: []
|
58
|
+
|
59
|
+
files:
|
60
|
+
- Rakefile
|
61
|
+
- lib/aleph.rb
|
62
|
+
- aleph.gemspec
|
63
|
+
- test/aleph.rb
|
64
|
+
- test/binary.rb
|
65
|
+
- test/simple.html
|
66
|
+
has_rdoc: true
|
67
|
+
homepage: http://github.com/djanowski/aleph
|
68
|
+
licenses: []
|
69
|
+
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
requirements: []
|
92
|
+
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 1.3.7
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Literate-programming HTML
|
98
|
+
test_files: []
|
99
|
+
|