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.

@@ -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.4'
17
- s.date = '2012-08-14'
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
@@ -29,10 +29,23 @@ $:.unshift(File.join(File.dirname(__FILE__), '..', 'vendor'))
29
29
  #
30
30
  # Examples:
31
31
  #
32
- # lines = File.readlines(filename)
32
+ # Use built-in templates:
33
33
  #
34
- # doc = Asciidoctor::Document.new(lines)
35
- # html = doc.render(template_path)
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 => /^\/\/\s/,
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' => '&#160;',
184
+ 'deg' => '&#176;',
185
+ 'zwsp' => '&#8203;',
186
+ 'lsquo' => '&#8216;',
187
+ 'rsquo' => '&#8217;',
188
+ 'ldquo' => '&#8220;',
189
+ 'rdquo' => '&#8221;',
190
+ 'wj' => '&#8288;',
191
+ 'amp' => '&',
192
+ 'lt' => '<',
193
+ 'gt' => '>',
160
194
  )
161
195
 
196
+ SPECIAL_CHARS = {
197
+ '<' => '&lt;',
198
+ '>' => '&gt;',
199
+ '&' => '&amp;'
200
+ }
201
+
162
202
  HTML_ELEMENTS = {
163
203
  'br-asciidoctor' => '<br/>'
164
204
  }
@@ -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 = line.gsub(/ (^|[^\\]) \{ (\w[\w\-_]+\w) \} /x) do
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!( /(^|[^`])(https?:\/\/[^\[ ]+)(\[+[^\]]*\]+)?/ ) do
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, '&ldquo;\1&rdquo;')
@@ -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!(/([\s\W])\*([^\*]+)\*([\s\W])/m, '\1<strong>\2</strong>\3')
311
- html.gsub!(/([\s\W])'(.+?)'([\s\W])/m, '\1<em>\2</em>\3')
312
- html.gsub!(/([\s\W])_([^_]+)_([\s\W])/m, '\1<em>\2</em>\3')
313
- html.gsub!(/([\s\W])\+([^\+]+)\+([\s\W])/m, '\1<tt>\2</tt>\3')
314
- html.gsub!(/([\s\W])\^([^\^]+)\^([\s\W])/m, '\1<sup>\2</sup>\3')
315
- html.gsub!(/([\s\W])\~([^\~]+)\~([\s\W])/m, '\1<sub>\2</sub>\3')
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
@@ -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)
@@ -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[:comment])
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
- new_block = next_block(section_reader, section) if section_reader.has_lines?
663
- section << new_block unless new_block.nil?
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Asciidoctor
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/noof.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'ap'
3
- require 'lib/asciidoctor'
3
+ require_relative 'lib/asciidoctor'
4
4
 
5
5
  lines = File.readlines("test/fixtures/asciidoc_index.txt")
6
6
  #lines = File.read("test/fixtures/asciidoc_index.txt")
@@ -77,12 +77,26 @@ context "Attributes" do
77
77
  pending "whut?"
78
78
  end
79
79
 
80
- test "Intrinsics" do
81
- Asciidoctor::INTRINSICS.each_pair do |key, value|
82
- html = render_string("Look, a {#{key}} is here")
83
- result = Nokogiri::HTML(html)
84
- assert_equal("Look, a #{value} is here", result.css("p").first.content.strip)
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&#160;together/, html
93
+ end
94
+
95
+ test "escape special characters" do
96
+ html = render_string('<node>&</node>')
97
+ assert_match /&lt;node&gt;&amp;&lt;\/node&gt;/, html
85
98
  end
99
+
86
100
  end
87
101
 
88
102
  end
@@ -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
- end
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
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ context "Links" do
4
+
5
+ test "absolute url with link prefix" do
6
+ assert_xpath "//a[@href='http://asciidoc.org']", render_string("We're parsing link:http://asciidoc.org[AsciiDoc] markup")
7
+ end
8
+
9
+ end
@@ -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
- end
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
@@ -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
@@ -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''''\n\n...from this!"), 1
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
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-08-14 00:00:00.000000000 Z
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