asciidoctor 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- data/asciidoctor.gemspec +3 -2
- data/lib/asciidoctor.rb +48 -8
- data/lib/asciidoctor/block.rb +15 -9
- data/lib/asciidoctor/debug.rb +5 -1
- data/lib/asciidoctor/lexer.rb +9 -3
- data/lib/asciidoctor/section.rb +1 -1
- data/lib/asciidoctor/version.rb +1 -1
- data/noof.rb +1 -1
- data/test/attributes_test.rb +19 -5
- data/test/headers_test.rb +12 -4
- data/test/links_test.rb +9 -0
- data/test/paragraphs_test.rb +16 -1
- data/test/test_helper.rb +2 -2
- data/test/text_test.rb +22 -2
- metadata +4 -2
data/asciidoctor.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
|
|
13
13
|
## If your rubyforge_project name is different, then edit it and comment out
|
14
14
|
## the sub! line in the Rakefile
|
15
15
|
s.name = 'asciidoctor'
|
16
|
-
s.version = '0.0.
|
17
|
-
s.date = '2012-
|
16
|
+
s.version = '0.0.5'
|
17
|
+
s.date = '2012-12-11'
|
18
18
|
s.rubyforge_project = 'asciidoctor'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
@@ -85,6 +85,7 @@ Gem::Specification.new do |s|
|
|
85
85
|
test/fixtures/list_elements.asciidoc
|
86
86
|
test/headers_test.rb
|
87
87
|
test/lexer_test.rb
|
88
|
+
test/links_test.rb
|
88
89
|
test/list_elements_test.rb
|
89
90
|
test/paragraphs_test.rb
|
90
91
|
test/reader_test.rb
|
data/lib/asciidoctor.rb
CHANGED
@@ -29,10 +29,23 @@ $:.unshift(File.join(File.dirname(__FILE__), '..', 'vendor'))
|
|
29
29
|
#
|
30
30
|
# Examples:
|
31
31
|
#
|
32
|
-
#
|
32
|
+
# Use built-in templates:
|
33
33
|
#
|
34
|
-
#
|
35
|
-
#
|
34
|
+
# lines = File.readlines("your_file.asc")
|
35
|
+
# doc = Asciidoctor::Document.new(lines)
|
36
|
+
# html = doc.render
|
37
|
+
# File.open("your_file.html", "w+") do |file|
|
38
|
+
# file.puts html
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# Use custom (Tilt-supported) templates:
|
42
|
+
#
|
43
|
+
# lines = File.readlines("your_file.asc")
|
44
|
+
# doc = Asciidoctor::Document.new(lines, :template_dir => 'templates')
|
45
|
+
# html = doc.render
|
46
|
+
# File.open("your_file.html", "w+") do |file|
|
47
|
+
# file.puts html
|
48
|
+
# end
|
36
49
|
module Asciidoctor
|
37
50
|
REGEXP = {
|
38
51
|
# [[Foo]] (also allows, say, [[[]] or [[[Foo[f]], but I don't think it is supposed to (TODO))
|
@@ -57,8 +70,13 @@ module Asciidoctor
|
|
57
70
|
# <1> Foo
|
58
71
|
:colist => /^(\<\d+\>)\s*(.*)/,
|
59
72
|
|
73
|
+
# ////
|
74
|
+
# comment block
|
75
|
+
# ////
|
76
|
+
:comment_blk => /^\/{4,}\s*$/,
|
77
|
+
|
60
78
|
# // (and then whatever)
|
61
|
-
:comment =>
|
79
|
+
:comment => /^\/\/[^\/]/,
|
62
80
|
|
63
81
|
# foo:: || foo;;
|
64
82
|
# Should be followed by a definition line, e.g.,
|
@@ -126,7 +144,7 @@ module Asciidoctor
|
|
126
144
|
# ____
|
127
145
|
:quote => /^_{4,}\s*$/,
|
128
146
|
|
129
|
-
# '''
|
147
|
+
# '''
|
130
148
|
:ruler => /^'{3,}\s*$/,
|
131
149
|
|
132
150
|
# ****
|
@@ -149,16 +167,38 @@ module Asciidoctor
|
|
149
167
|
INTRINSICS = Hash.new{|h,k| STDERR.puts "Missing intrinsic: #{k.inspect}"; "{#{k}}"}.merge(
|
150
168
|
'startsb' => '[',
|
151
169
|
'endsb' => ']',
|
170
|
+
'brvbar' => '|',
|
152
171
|
'caret' => '^',
|
153
172
|
'asterisk' => '*',
|
154
173
|
'tilde' => '~',
|
155
174
|
'litdd' => '--',
|
156
175
|
'plus' => '+',
|
157
|
-
'apostrophe' =>
|
158
|
-
'backslash' =>
|
159
|
-
'backtick' => '`'
|
176
|
+
'apostrophe' => '\'',
|
177
|
+
'backslash' => '\\',
|
178
|
+
'backtick' => '`',
|
179
|
+
'empty' => '',
|
180
|
+
'sp' => ' ',
|
181
|
+
'two-colons' => '::',
|
182
|
+
'two-semicolons' => ';;',
|
183
|
+
'nbsp' => ' ',
|
184
|
+
'deg' => '°',
|
185
|
+
'zwsp' => '​',
|
186
|
+
'lsquo' => '‘',
|
187
|
+
'rsquo' => '’',
|
188
|
+
'ldquo' => '“',
|
189
|
+
'rdquo' => '”',
|
190
|
+
'wj' => '⁠',
|
191
|
+
'amp' => '&',
|
192
|
+
'lt' => '<',
|
193
|
+
'gt' => '>',
|
160
194
|
)
|
161
195
|
|
196
|
+
SPECIAL_CHARS = {
|
197
|
+
'<' => '<',
|
198
|
+
'>' => '>',
|
199
|
+
'&' => '&'
|
200
|
+
}
|
201
|
+
|
162
202
|
HTML_ELEMENTS = {
|
163
203
|
'br-asciidoctor' => '<br/>'
|
164
204
|
}
|
data/lib/asciidoctor/block.rb
CHANGED
@@ -192,8 +192,9 @@ class Asciidoctor::Block
|
|
192
192
|
|
193
193
|
result = lines.map do |line|
|
194
194
|
Asciidoctor.debug "#{__method__} -> Processing line: #{line}"
|
195
|
+
f = sub_special_chars(line)
|
195
196
|
# gsub! doesn't have lookbehind, so we have to capture and re-insert
|
196
|
-
f =
|
197
|
+
f = f.gsub(/ (^|[^\\]) \{ (\w([\w\-_]+)?\w) \} /x) do
|
197
198
|
if self.document.defines.has_key?($2)
|
198
199
|
# Substitute from user defines first
|
199
200
|
$1 + self.document.defines[$2]
|
@@ -273,7 +274,7 @@ class Asciidoctor::Block
|
|
273
274
|
html.gsub!( /(^|[^<])<<([^<>,]+)(,([^>]*))?>>/ ) { "#{$1}link:##{$2}[" + ($4.nil? ? document.references[$2] : $4).to_s + "]" }
|
274
275
|
|
275
276
|
# Do the same with URLs
|
276
|
-
html.gsub!( /(^|[
|
277
|
+
html.gsub!( /(^|[^(`|link:)])(https?:\/\/[^\[ ]+)(\[+[^\]]*\]+)?/ ) do
|
277
278
|
pre = $1
|
278
279
|
url = $2
|
279
280
|
link = ( $3 || $2 ).gsub( /(^\[|\]$)/,'' )
|
@@ -282,7 +283,6 @@ class Asciidoctor::Block
|
|
282
283
|
"#{pre}link:#{url}[#{link}]"
|
283
284
|
end
|
284
285
|
|
285
|
-
html = CGI.escapeHTML(html)
|
286
286
|
html.gsub!(Asciidoctor::REGEXP[:biblio], '<a name="\1">[\1]</a>')
|
287
287
|
html.gsub!(Asciidoctor::REGEXP[:ruler], '<hr>\n')
|
288
288
|
html.gsub!(/``([^`']*)''/m, '“\1”')
|
@@ -307,12 +307,14 @@ class Asciidoctor::Block
|
|
307
307
|
|
308
308
|
# "Constrained" quotes, which must be bounded by white space or
|
309
309
|
# common punctuation characters
|
310
|
-
html.gsub!(/(
|
311
|
-
html.gsub!(/(
|
312
|
-
|
313
|
-
html.gsub!(/(
|
314
|
-
html.gsub!(/(
|
315
|
-
html.gsub!(/(
|
310
|
+
html.gsub!(/(^|\s|\W)\*([^\*]+)\*(\s|\W|$)/m, '\1<strong>\2</strong>\3')
|
311
|
+
html.gsub!(/(^|\s|\W)'(.+?)'(\s|\W|$)/m, '\1<em>\2</em>\3')
|
312
|
+
# restore escaped single quotes after processing emphasis
|
313
|
+
html.gsub!(/(\w)\\'(\w)/, '\1\'\2')
|
314
|
+
html.gsub!(/(^|\s|\W)_([^_]+)_(\s|\W|$)/m, '\1<em>\2</em>\3')
|
315
|
+
html.gsub!(/(^|\s|\W)\+([^\+]+)\+(\s|\W|$)/m, '\1<tt>\2</tt>\3')
|
316
|
+
html.gsub!(/(^|\s|\W)\^([^\^]+)\^(\s|\W|$)/m, '\1<sup>\2</sup>\3')
|
317
|
+
html.gsub!(/(^|\s|\W)\~([^\~]+)\~(\s|\W|$)/m, '\1<sub>\2</sub>\3')
|
316
318
|
|
317
319
|
html.gsub!(/\\([\{\}\-])/, '\1')
|
318
320
|
html.gsub!(/linkgit:([^\]]+)\[(\d+)\]/, '<a href="\1.html">\1(\2)</a>')
|
@@ -321,5 +323,9 @@ class Asciidoctor::Block
|
|
321
323
|
html
|
322
324
|
end
|
323
325
|
end
|
326
|
+
|
327
|
+
def sub_special_chars(str)
|
328
|
+
str.gsub(/[#{Asciidoctor::SPECIAL_CHARS.keys.join}]/) {|match| Asciidoctor::SPECIAL_CHARS[match] }
|
329
|
+
end
|
324
330
|
# end private
|
325
331
|
end
|
data/lib/asciidoctor/debug.rb
CHANGED
@@ -3,8 +3,12 @@ module Asciidoctor
|
|
3
3
|
puts *args if self.show_debug_output?
|
4
4
|
end
|
5
5
|
|
6
|
+
def self.set_debug(value)
|
7
|
+
@show_debug = value
|
8
|
+
end
|
9
|
+
|
6
10
|
def self.show_debug_output?
|
7
|
-
ENV['DEBUG'] == 'true' && ENV['SUPPRESS_DEBUG'] != 'true'
|
11
|
+
@show_debug || (ENV['DEBUG'] == 'true' && ENV['SUPPRESS_DEBUG'] != 'true')
|
8
12
|
end
|
9
13
|
|
10
14
|
def self.puts_indented(level, *args)
|
data/lib/asciidoctor/lexer.rb
CHANGED
@@ -63,7 +63,11 @@ class Asciidoctor::Lexer
|
|
63
63
|
this_line = reader.get_line
|
64
64
|
next_line = reader.peek_line || ''
|
65
65
|
|
66
|
-
if this_line.match(REGEXP[:
|
66
|
+
if this_line.match(REGEXP[:comment_blk])
|
67
|
+
Reader.new(reader.grab_lines_until {|line| line.match( REGEXP[:comment_blk] ) })
|
68
|
+
next
|
69
|
+
|
70
|
+
elsif this_line.match(REGEXP[:comment])
|
67
71
|
next
|
68
72
|
|
69
73
|
elsif match = this_line.match(REGEXP[:title])
|
@@ -659,8 +663,10 @@ class Asciidoctor::Lexer
|
|
659
663
|
while section_reader.has_lines?
|
660
664
|
section_reader.skip_blank
|
661
665
|
|
662
|
-
|
663
|
-
|
666
|
+
if section_reader.has_lines?
|
667
|
+
new_block = next_block(section_reader, section)
|
668
|
+
section << new_block unless new_block.nil?
|
669
|
+
end
|
664
670
|
end
|
665
671
|
|
666
672
|
section
|
data/lib/asciidoctor/section.rb
CHANGED
@@ -68,7 +68,7 @@ class Asciidoctor::Section
|
|
68
68
|
# section.section_id
|
69
69
|
# => "_foo"
|
70
70
|
def section_id
|
71
|
-
"_#{name && name.downcase.gsub(' ','_')
|
71
|
+
"_#{name && name.downcase.gsub(/\W+/,'_').gsub(/_+$/, '')}".tr_s('_', '_')
|
72
72
|
end
|
73
73
|
|
74
74
|
# Public: Get the Asciidoctor::Document instance to which this Block belongs
|
data/lib/asciidoctor/version.rb
CHANGED
data/noof.rb
CHANGED
data/test/attributes_test.rb
CHANGED
@@ -77,12 +77,26 @@ context "Attributes" do
|
|
77
77
|
pending "whut?"
|
78
78
|
end
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
80
|
+
context "intrinsics" do
|
81
|
+
|
82
|
+
test "substitute intrinsics" do
|
83
|
+
Asciidoctor::INTRINSICS.each_pair do |key, value|
|
84
|
+
html = render_string("Look, a {#{key}} is here")
|
85
|
+
# can't use Nokogiri because it interprets the HTML entities and we can't match them
|
86
|
+
assert_match /Look, a #{Regexp.escape(value)} is here/, html
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
test "don't escape intrinsic substitutions" do
|
91
|
+
html = render_string('happy{nbsp}together')
|
92
|
+
assert_match /happy together/, html
|
93
|
+
end
|
94
|
+
|
95
|
+
test "escape special characters" do
|
96
|
+
html = render_string('<node>&</node>')
|
97
|
+
assert_match /<node>&<\/node>/, html
|
85
98
|
end
|
99
|
+
|
86
100
|
end
|
87
101
|
|
88
102
|
end
|
data/test/headers_test.rb
CHANGED
@@ -7,13 +7,21 @@ context "Headers" do
|
|
7
7
|
|
8
8
|
context "level 1" do
|
9
9
|
test "with multiline syntax" do
|
10
|
-
assert_xpath "//h2", render_string("My Section\n-----------")
|
10
|
+
assert_xpath "//h2[@id='_my_section']", render_string("My Section\n-----------")
|
11
11
|
end
|
12
12
|
|
13
13
|
test "with single line syntax" do
|
14
|
-
assert_xpath "//h2", render_string("== My Title")
|
14
|
+
assert_xpath "//h2[@id='_my_title']", render_string("== My Title")
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
|
+
test "with non-word character" do
|
18
|
+
assert_xpath "//h2[@id='_where_s_the_love']", render_string("== Where's the love?")
|
19
|
+
end
|
20
|
+
|
21
|
+
test "with sequential non-word characters" do
|
22
|
+
assert_xpath "//h2[@id='_what_the_is_that']", render_string('== What the #@$ is that')
|
23
|
+
end
|
24
|
+
end
|
17
25
|
|
18
26
|
context "level 2" do
|
19
27
|
test "with multiline syntax" do
|
@@ -44,4 +52,4 @@ context "Headers" do
|
|
44
52
|
assert_xpath "//h5", render_string("===== My Title")
|
45
53
|
end
|
46
54
|
end
|
47
|
-
end
|
55
|
+
end
|
data/test/links_test.rb
ADDED
data/test/paragraphs_test.rb
CHANGED
@@ -12,6 +12,11 @@ context "Paragraphs" do
|
|
12
12
|
assert_xpath "//p", rendered, 2
|
13
13
|
end
|
14
14
|
|
15
|
+
test "no duplicate block before next section" do
|
16
|
+
rendered = render_string("Title\n=====\n\nPreamble.\n\n== First Section\n\nParagraph 1\n\nParagraph 2\n\n\n== Second Section\n\nLast words")
|
17
|
+
assert_xpath '//p[text()="Paragraph 2"]', rendered, 1
|
18
|
+
end
|
19
|
+
|
15
20
|
context "code" do
|
16
21
|
test "literal paragraph" do
|
17
22
|
assert_xpath "//pre/tt", render_string(" LITERALS\n\n ARE LITERALLY\n\n AWESOMMMME.")
|
@@ -35,4 +40,14 @@ context "Paragraphs" do
|
|
35
40
|
assert_xpath "//div[@class='admonitionblock']", render_string("NOTE: This is important, fool!")
|
36
41
|
end
|
37
42
|
end
|
38
|
-
|
43
|
+
|
44
|
+
context "comments" do
|
45
|
+
test "line comment" do
|
46
|
+
assert_no_match /comment/, render_string("first paragraph\n\n//comment\n\nsecond paragraph")
|
47
|
+
end
|
48
|
+
|
49
|
+
test "comment block" do
|
50
|
+
assert_no_match /comment/, render_string("first paragraph\n\n////\ncomment\n////\n\nsecond paragraph")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -3,7 +3,7 @@ require 'test/unit'
|
|
3
3
|
|
4
4
|
require "#{File.expand_path(File.dirname(__FILE__))}/../lib/asciidoctor.rb"
|
5
5
|
|
6
|
-
require 'mocha'
|
6
|
+
require 'mocha/setup'
|
7
7
|
require 'htmlentities'
|
8
8
|
require 'nokogiri'
|
9
9
|
require 'pending'
|
@@ -145,4 +145,4 @@ end
|
|
145
145
|
|
146
146
|
def context(*name, &block)
|
147
147
|
Test::Unit::TestCase.context(name, &block)
|
148
|
-
end
|
148
|
+
end
|
data/test/text_test.rb
CHANGED
@@ -16,13 +16,33 @@ context "Text" do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
test "separator" do
|
19
|
-
assert_xpath "//hr", render_string("This is separated.\n\n'''
|
19
|
+
assert_xpath "//hr", render_string("This is separated.\n\n'''\n\n...from this!"), 1
|
20
20
|
end
|
21
21
|
|
22
22
|
test "emphasized text" do
|
23
23
|
assert_xpath "//em", render_string("An 'emphatic' no")
|
24
24
|
end
|
25
25
|
|
26
|
+
test "emphasized text with escaped single quote" do
|
27
|
+
assert_xpath "//em[text()=\"Johnny's\"]", render_string("It's 'Johnny\\'s' phone")
|
28
|
+
end
|
29
|
+
|
30
|
+
test "escaped single quote is restore as single quote" do
|
31
|
+
assert_xpath "//p[contains(text(), \"Let's do it!\")]", render_string("Let\\'s do it!")
|
32
|
+
end
|
33
|
+
|
34
|
+
test "emphasized text at end of line" do
|
35
|
+
assert_xpath "//em", render_string("This library is 'awesome'")
|
36
|
+
end
|
37
|
+
|
38
|
+
test "emphasized text at beginning of line" do
|
39
|
+
assert_xpath "//em", render_string("'drop' it")
|
40
|
+
end
|
41
|
+
|
42
|
+
test "emphasized text across line" do
|
43
|
+
assert_xpath "//em", render_string("'check it'")
|
44
|
+
end
|
45
|
+
|
26
46
|
test "unquoted text" do
|
27
47
|
assert_no_match /#/, render_string("An #unquoted# word")
|
28
48
|
end
|
@@ -74,4 +94,4 @@ context "Text" do
|
|
74
94
|
assert_xpath "//tt", rendered_chars
|
75
95
|
end
|
76
96
|
end
|
77
|
-
end
|
97
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciidoctor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-12-11 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -144,6 +144,7 @@ files:
|
|
144
144
|
- test/fixtures/list_elements.asciidoc
|
145
145
|
- test/headers_test.rb
|
146
146
|
- test/lexer_test.rb
|
147
|
+
- test/links_test.rb
|
147
148
|
- test/list_elements_test.rb
|
148
149
|
- test/paragraphs_test.rb
|
149
150
|
- test/reader_test.rb
|
@@ -179,6 +180,7 @@ test_files:
|
|
179
180
|
- test/document_test.rb
|
180
181
|
- test/headers_test.rb
|
181
182
|
- test/lexer_test.rb
|
183
|
+
- test/links_test.rb
|
182
184
|
- test/list_elements_test.rb
|
183
185
|
- test/paragraphs_test.rb
|
184
186
|
- test/reader_test.rb
|