asciidoctor 0.0.5 → 0.0.6
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/README.asciidoc +156 -0
- data/asciidoctor.gemspec +5 -4
- data/lib/asciidoctor.rb +46 -34
- data/lib/asciidoctor/block.rb +59 -42
- data/lib/asciidoctor/document.rb +56 -20
- data/lib/asciidoctor/lexer.rb +204 -107
- data/lib/asciidoctor/list_item.rb +47 -14
- data/lib/asciidoctor/reader.rb +29 -14
- data/lib/asciidoctor/render_templates.rb +162 -64
- data/lib/asciidoctor/renderer.rb +3 -3
- data/lib/asciidoctor/section.rb +32 -6
- data/lib/asciidoctor/version.rb +1 -1
- data/test/attributes_test.rb +44 -4
- data/test/document_test.rb +21 -2
- data/test/headers_test.rb +72 -13
- data/test/lexer_test.rb +54 -0
- data/test/lists_test.rb +406 -0
- data/test/paragraphs_test.rb +103 -3
- data/test/preamble_test.rb +88 -0
- data/test/test_helper.rb +6 -5
- data/test/text_test.rb +2 -1
- metadata +7 -5
- data/README.md +0 -154
- data/test/list_elements_test.rb +0 -55
data/README.asciidoc
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
[float]
|
2
|
+
Asciidoctor
|
3
|
+
===========
|
4
|
+
:gitscm-next: https://github.com/github/gitscm-next
|
5
|
+
:tilt: https://github.com/rtomayko/tilt
|
6
|
+
:freesoftware: http://www.fsf.org/licensing/essays/free-sw.html
|
7
|
+
:issues: https://github.com/erebor/asciidoctor/issues
|
8
|
+
:gist: https://gist.github.com
|
9
|
+
:fork: http://help.github.com/fork-a-repo/
|
10
|
+
:branch: http://learn.github.com/p/branching.html
|
11
|
+
:pr: http://help.github.com/send-pull-requests/
|
12
|
+
:license: https://github.com/erebor/asciidoctor/blob/master/LICENSE
|
13
|
+
|
14
|
+
http://github.com/erebor/asciidoctor[Asciidoctor] is a pure-Ruby
|
15
|
+
processor for turning
|
16
|
+
http://www.methods.co.nz/asciidoc/index.html[AsciiDoc] documents or
|
17
|
+
strings into HTML (and, eventually other formats as well...'stay
|
18
|
+
tuned!').
|
19
|
+
|
20
|
+
Asciidoctor uses simple built-in ERB templates to style the output in
|
21
|
+
a way that roughly matches the default HTML output of the native
|
22
|
+
Python processor. You can override this behavior by providing
|
23
|
+
{tilt}[Tilt]-compatible templates. See the xref:usage[Usage section]
|
24
|
+
for more details.
|
25
|
+
|
26
|
+
Asciidoctor currently works with Ruby 1.8.7 and 1.9.3, though I don't
|
27
|
+
know of any reason it shouldn't work with more exotic Ruby versions,
|
28
|
+
and would welcome help in testing that out.
|
29
|
+
|
30
|
+
The initial code from which Asciidoctor started was from the
|
31
|
+
{gitscm-next}[Git SCM site repo].
|
32
|
+
|
33
|
+
== Installation
|
34
|
+
|
35
|
+
NOTE: This gem is very immature, and as yet only supports a small
|
36
|
+
subset of AsciiDoc features. Thus, you should only use it if you have
|
37
|
+
a high tolerance for bugs, failures, and generally bad and intemperate
|
38
|
+
behavior.
|
39
|
+
|
40
|
+
To install the gem:
|
41
|
+
|
42
|
+
gem install asciidoctor
|
43
|
+
|
44
|
+
Or if you prefer bundler:
|
45
|
+
|
46
|
+
bundle install asciidoctor
|
47
|
+
|
48
|
+
== Usage
|
49
|
+
|
50
|
+
To render a file containing AsciiDoc markup to HTML:
|
51
|
+
|
52
|
+
lines = File.readlines('your_file.asciidoc')
|
53
|
+
doc = Asciidoctor::Document.new(lines)
|
54
|
+
html = doc.render
|
55
|
+
File.open('your_file.html', 'w+') do |file|
|
56
|
+
file.puts html
|
57
|
+
end
|
58
|
+
|
59
|
+
To render an AsciiDoc-formatted string:
|
60
|
+
|
61
|
+
doc = Asciidoctor::Document.new("*This* is it.")
|
62
|
+
puts doc.render
|
63
|
+
|
64
|
+
Asciidoctor allows you to override the default template used to render
|
65
|
+
almost any individual AsciiDoc element. If you provide a directory of
|
66
|
+
{tilt}[Tilt]-compatible templates, named in such a way that Asciidoctor
|
67
|
+
can figure out which template goes with which element, Asciidoctor will
|
68
|
+
use the templates in this directory instead of its built-in templates
|
69
|
+
for any elements for which it finds a matching template. It will
|
70
|
+
fallback to its default templates for everything else.
|
71
|
+
|
72
|
+
doc = Asciidoctor::Document.new("*This* is it.", :template_dir => 'templates')
|
73
|
+
puts doc.render
|
74
|
+
|
75
|
+
The Document and Section templates should begin with `document.` and
|
76
|
+
`section.`, respectively. The file extension will depend on which
|
77
|
+
Tilt-compatible format you've chosen. For ERB, the template names would be
|
78
|
+
`document.html.erb` and `section.html.erb`, for instance. For Haml, they
|
79
|
+
would be `document.html.haml` and `section.html.haml`.
|
80
|
+
|
81
|
+
Templates for specific elements, like a Paragraph or Anchor, would begin
|
82
|
+
with `section_<element>.`. For instance, to override the default Paragraph
|
83
|
+
template with an ERB template, put a file called `section_paragraph.html.erb`
|
84
|
+
in the template directory you pass in to `Document.new`.
|
85
|
+
|
86
|
+
For more usage examples, see the test suite.
|
87
|
+
|
88
|
+
== Contributing
|
89
|
+
|
90
|
+
In the spirit of {freesoftware}[free software], 'everyone' is
|
91
|
+
encouraged to help improve this project.
|
92
|
+
|
93
|
+
Here are some ways *you* can contribute:
|
94
|
+
|
95
|
+
* by using alpha, beta, and prerelease versions
|
96
|
+
* by reporting bugs
|
97
|
+
* by suggesting new features
|
98
|
+
* by writing or editing documentation
|
99
|
+
* by writing specifications
|
100
|
+
* by writing code ('No patch is too small.' Fix typos, add comments,
|
101
|
+
clean up inconsistent whitespace, etc.)
|
102
|
+
* by refactoring code
|
103
|
+
* by fixing {issues}[issues]
|
104
|
+
* by reviewing patches
|
105
|
+
|
106
|
+
== Submitting an Issue
|
107
|
+
|
108
|
+
We use the {issues}[GitHub issue tracker] associated with this project
|
109
|
+
to track bugs and features. Before submitting a bug report or feature
|
110
|
+
request, check to make sure it hasn't already been submitted. When
|
111
|
+
submitting a bug report, please include a {gist}[Gist] that includes
|
112
|
+
any details that may help reproduce the bug, including your gem
|
113
|
+
version, Ruby version, and operating system.
|
114
|
+
|
115
|
+
Most importantly, since Asciidoctor is a text processor, reproducing
|
116
|
+
most bugs requires that we have some snippet of text on which
|
117
|
+
Asciidoctor exhibits the bad behavior.
|
118
|
+
|
119
|
+
An ideal bug report would include a pull request with failing specs.
|
120
|
+
|
121
|
+
== Submitting a Pull Request
|
122
|
+
|
123
|
+
. {fork}[Fork the repository].
|
124
|
+
. {branch}[Create a topic branch].
|
125
|
+
. Add tests for your unimplemented feature or bug fix.
|
126
|
+
. Run `bundle exec rake`. If your tests pass, return to step 3.
|
127
|
+
. Implement your feature or bug fix.
|
128
|
+
. Run `bundle exec rake`. If your tests fail, return to step 5.
|
129
|
+
. Add documentation for your feature or bug fix.
|
130
|
+
. If your changes are not 100% documented, go back to step 7.
|
131
|
+
. Add, commit, and push your changes.
|
132
|
+
. {pr}[Submit a pull request].
|
133
|
+
|
134
|
+
|
135
|
+
== Supported Ruby Versions
|
136
|
+
|
137
|
+
This library aims to support the following Ruby implementations:
|
138
|
+
|
139
|
+
* Ruby 1.8.7
|
140
|
+
* Ruby 1.9.3
|
141
|
+
|
142
|
+
If something doesn't work on one of these interpreters, it should be
|
143
|
+
considered a bug.
|
144
|
+
|
145
|
+
If you would like this library to support another Ruby version, you
|
146
|
+
may volunteer to be a maintainer. Being a maintainer entails making
|
147
|
+
sure all tests run and pass on that implementation. When something
|
148
|
+
breaks on your implementation, you will be personally responsible for
|
149
|
+
providing patches in a timely fashion. If critical issues for a
|
150
|
+
particular implementation exist at the time of a major release,
|
151
|
+
support for that Ruby version may be dropped.
|
152
|
+
|
153
|
+
== Copyright
|
154
|
+
|
155
|
+
Copyright (c) 2012 Ryan Waldron.
|
156
|
+
See {license}[LICENSE] for details.
|
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-12-
|
16
|
+
s.version = '0.0.6'
|
17
|
+
s.date = '2012-12-17'
|
18
18
|
s.rubyforge_project = 'asciidoctor'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
@@ -59,7 +59,7 @@ Gem::Specification.new do |s|
|
|
59
59
|
# = MANIFEST =
|
60
60
|
s.files = %w[
|
61
61
|
LICENSE
|
62
|
-
README.
|
62
|
+
README.asciidoc
|
63
63
|
Rakefile
|
64
64
|
asciidoctor.gemspec
|
65
65
|
bin/asciidoctor
|
@@ -86,8 +86,9 @@ Gem::Specification.new do |s|
|
|
86
86
|
test/headers_test.rb
|
87
87
|
test/lexer_test.rb
|
88
88
|
test/links_test.rb
|
89
|
-
test/
|
89
|
+
test/lists_test.rb
|
90
90
|
test/paragraphs_test.rb
|
91
|
+
test/preamble_test.rb
|
91
92
|
test/reader_test.rb
|
92
93
|
test/test_helper.rb
|
93
94
|
test/text_test.rb
|
data/lib/asciidoctor.rb
CHANGED
@@ -47,6 +47,14 @@ $:.unshift(File.join(File.dirname(__FILE__), '..', 'vendor'))
|
|
47
47
|
# file.puts html
|
48
48
|
# end
|
49
49
|
module Asciidoctor
|
50
|
+
# The default document type
|
51
|
+
# Can influence markup generated by render templates
|
52
|
+
DEFAULT_DOCTYPE = 'article'
|
53
|
+
|
54
|
+
LIST_CONTEXTS = [:ulist, :olist, :dlist]
|
55
|
+
|
56
|
+
LIST_CONTINUATION = '+'
|
57
|
+
|
50
58
|
REGEXP = {
|
51
59
|
# [[Foo]] (also allows, say, [[[]] or [[[Foo[f]], but I don't think it is supposed to (TODO))
|
52
60
|
:anchor => /^\[(\[.+\])\]\s*$/,
|
@@ -59,14 +67,19 @@ module Asciidoctor
|
|
59
67
|
# a forced line break. This should be the same regexp as :line_break,
|
60
68
|
# below, but it gets its own entry because readability ftw, even
|
61
69
|
# though repeating regexps ftl.
|
62
|
-
:attr_continue =>
|
70
|
+
:attr_continue => /^(.*)[[:blank:]]\+[[:blank:]]*$/,
|
71
|
+
|
72
|
+
# An attribute list above a block element
|
73
|
+
#
|
74
|
+
# Can be strictly positional:
|
75
|
+
# [quote, Adam Smith, Wealth of Nations]
|
76
|
+
# Or can have name/value pairs
|
77
|
+
# [NOTE, caption="Good to know"]
|
78
|
+
:attr_list_blk => /^\[(\w.*)\]$/,
|
63
79
|
|
64
80
|
# [[[Foo]]] (does not suffer quite the same malady as :anchor, but almost. Allows [ but not ] in internal capture
|
65
81
|
:biblio => /\[\[\[([^\]]+)\]\]\]/,
|
66
82
|
|
67
|
-
# [caption="Foo"]
|
68
|
-
:caption => /^\[caption=\"([^\"]+)\"\]/,
|
69
|
-
|
70
83
|
# <1> Foo
|
71
84
|
:colist => /^(\<\d+\>)\s*(.*)/,
|
72
85
|
|
@@ -76,25 +89,40 @@ module Asciidoctor
|
|
76
89
|
:comment_blk => /^\/{4,}\s*$/,
|
77
90
|
|
78
91
|
# // (and then whatever)
|
79
|
-
:comment => /^\/\/[^\/]/,
|
92
|
+
:comment => /^\/\/([^\/]|$)/,
|
80
93
|
|
81
94
|
# foo:: || foo;;
|
82
95
|
# Should be followed by a definition line, e.g.,
|
83
96
|
# foo::
|
84
97
|
# That which precedes 'bar' (see also, bar)
|
85
|
-
:dlist =>
|
86
|
-
|
98
|
+
:dlist => /^\s*(?:\[\[([^\]]*)\]\])?(\w.*?)(:{2,4}|;;)(\s+(.*))?$/,
|
99
|
+
:dlist_siblings => {
|
100
|
+
# (?:.*?[^:])? - a non-capturing group which grabs longest sequence of characters that doesn't end w/ colon
|
101
|
+
'::' => /^\s*(?:\[\[([^\]]*)\]\])?(\w(?:.*[^:])?)(::)(\s+(.*))?$/,
|
102
|
+
':::' => /^\s*(?:\[\[([^\]]*)\]\])?(\w(?:.*[^:])?)(:::)(\s+(.*))?$/,
|
103
|
+
'::::' => /^\s*(?:\[\[([^\]]*)\]\])?(\w(?:.*[^:])?)(::::)(\s+(.*))?$/,
|
104
|
+
';;' => /^\s*(?:\[\[([^\]]*)\]\])?(\w.*)(;;)(\s+(.*))?$/
|
105
|
+
},
|
87
106
|
# ====
|
88
107
|
:example => /^={4,}\s*$/,
|
89
108
|
|
109
|
+
# image::filename.png[Caption]
|
110
|
+
:image_blk => /^image::(\S+?)\[(.*?)\]$/,
|
111
|
+
|
90
112
|
# == Foo
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#
|
97
|
-
|
113
|
+
# ^ yields a level 2 title
|
114
|
+
#
|
115
|
+
# == Foo ==
|
116
|
+
# ^ also yields a level 2 title
|
117
|
+
#
|
118
|
+
# both equivalent to this two-line version:
|
119
|
+
# Foo
|
120
|
+
# ~~~
|
121
|
+
#
|
122
|
+
# match[1] is the delimiter, whose length determines the level
|
123
|
+
# match[2] is the title itself
|
124
|
+
# match[3] is an optional repeat of the delimiter, which is dropped
|
125
|
+
:level_title => /^(={1,5})\s+(\S.*?)\s*(\s\1)?$/,
|
98
126
|
|
99
127
|
# ====== || ------ || ~~~~~~ || ^^^^^^ || ++++++
|
100
128
|
:line => /^([=\-~^\+])+\s*$/,
|
@@ -103,26 +131,14 @@ module Asciidoctor
|
|
103
131
|
# least one space character at the end of a non-blank line forces
|
104
132
|
# a line break. It generates a line break (br) tag for HTML outputs.
|
105
133
|
#
|
106
|
-
# This is the correct regexp to match what the User Guide actually
|
107
|
-
# says to do:
|
108
|
-
# :line_break => /^(.*(?:\S+)+.*)\s\+$/,
|
109
|
-
#
|
110
|
-
# But the regexp we're using (below), is what asciidoc *actually*
|
111
|
-
# does for HTML output, courtesy of the default html4.conf file (under
|
112
|
-
# the [replacements2] section).
|
113
|
-
#
|
114
134
|
# + (would not match because there's no space before +)
|
115
135
|
# + (would match and capture '')
|
116
136
|
# Foo + (would and capture 'Foo')
|
117
|
-
:line_break =>
|
137
|
+
:line_break => /([[:blank:]])\+[[:blank:]]*$/,
|
118
138
|
|
119
139
|
# ----
|
120
140
|
:listing => /^\-{4,}\s*$/,
|
121
141
|
|
122
|
-
# [source, ruby]
|
123
|
-
# Treats the next paragraph as a :listing block
|
124
|
-
:listing_source => /^\[source,\s*([^\]]+)\]\s*$/,
|
125
|
-
|
126
142
|
# ....
|
127
143
|
:lit_blk => /^\.{4,}\s*$/,
|
128
144
|
|
@@ -132,9 +148,6 @@ module Asciidoctor
|
|
132
148
|
# "Wooble" || Wooble
|
133
149
|
:name => /^(["A-Za-z].*)\s*$/, # I believe this fails to require " chars to be paired (TODO)
|
134
150
|
|
135
|
-
# [NOTE]
|
136
|
-
:note => /^\[NOTE\]\s*$/,
|
137
|
-
|
138
151
|
# --
|
139
152
|
:oblock => /^\-\-\s*$/,
|
140
153
|
|
@@ -158,12 +171,11 @@ module Asciidoctor
|
|
158
171
|
:title => /^\.([^\s\.].*)\s*$/,
|
159
172
|
|
160
173
|
# * Foo || - Foo
|
161
|
-
:ulist => /^ \s* (- | \*{1,5}) \s+ (.*) $/x
|
162
|
-
|
163
|
-
# [verse]
|
164
|
-
:verse => /^\[verse\]\s*$/
|
174
|
+
:ulist => /^ \s* (- | \*{1,5}) \s+ (.*) $/x
|
165
175
|
}
|
166
176
|
|
177
|
+
ADMONITION_STYLES = ['NOTE', 'TIP', 'IMPORTANT', 'WARNING', 'CAUTION']
|
178
|
+
|
167
179
|
INTRINSICS = Hash.new{|h,k| STDERR.puts "Missing intrinsic: #{k.inspect}"; "{#{k}}"}.merge(
|
168
180
|
'startsb' => '[',
|
169
181
|
'endsb' => ']',
|
data/lib/asciidoctor/block.rb
CHANGED
@@ -9,6 +9,12 @@ class Asciidoctor::Block
|
|
9
9
|
# Public: Get the Symbol context for this section block.
|
10
10
|
attr_reader :context
|
11
11
|
|
12
|
+
# Public: Create alias for context to be consistent w/ AsciiDoc
|
13
|
+
alias :blockname :context
|
14
|
+
|
15
|
+
# Public: Get the Hash of attributes for this block
|
16
|
+
attr_reader :attributes
|
17
|
+
|
12
18
|
# Public: Get the Array of sub-blocks for this section block.
|
13
19
|
attr_reader :blocks
|
14
20
|
|
@@ -17,6 +23,7 @@ class Asciidoctor::Block
|
|
17
23
|
|
18
24
|
# Public: Get/Set the String section anchor name.
|
19
25
|
attr_accessor :anchor
|
26
|
+
alias :id :anchor
|
20
27
|
|
21
28
|
# Public: Get/Set the Integer block level (for nested elements, like
|
22
29
|
# list elements).
|
@@ -41,7 +48,7 @@ class Asciidoctor::Block
|
|
41
48
|
@parent = parent
|
42
49
|
@context = context
|
43
50
|
@buffer = buffer
|
44
|
-
|
51
|
+
@attributes = {}
|
45
52
|
@blocks = []
|
46
53
|
end
|
47
54
|
|
@@ -51,9 +58,23 @@ class Asciidoctor::Block
|
|
51
58
|
@document = (@parent.is_a?(Asciidoctor::Document) ? @parent : @parent.document)
|
52
59
|
end
|
53
60
|
|
61
|
+
def attr(name, default = nil)
|
62
|
+
default.nil? ? @attributes.fetch(name.to_s, self.document.attr(name)) :
|
63
|
+
@attributes.fetch(name.to_s, self.document.attr(name, default))
|
64
|
+
end
|
65
|
+
|
66
|
+
def attr?(name)
|
67
|
+
@attributes.has_key?(name.to_s) || self.document.attr?(name)
|
68
|
+
end
|
69
|
+
|
70
|
+
def update_attributes(attributes)
|
71
|
+
@attributes.update(attributes)
|
72
|
+
end
|
73
|
+
|
54
74
|
# Public: Get the Asciidoctor::Renderer instance being used for the ancestor
|
55
75
|
# Asciidoctor::Document instance.
|
56
76
|
def renderer
|
77
|
+
# wouldn't @parent.renderer work here? I believe so
|
57
78
|
document.renderer
|
58
79
|
end
|
59
80
|
|
@@ -128,48 +149,30 @@ class Asciidoctor::Block
|
|
128
149
|
# * super/sub script
|
129
150
|
def content
|
130
151
|
|
131
|
-
Asciidoctor.debug "For the record, buffer is:"
|
132
|
-
Asciidoctor.debug @buffer.inspect
|
152
|
+
#Asciidoctor.debug "For the record, buffer is:"
|
153
|
+
#Asciidoctor.debug @buffer.inspect
|
133
154
|
|
134
155
|
case @context
|
135
|
-
when :
|
136
|
-
@buffer.map do |dt, dd|
|
137
|
-
if !dt.anchor.nil? && !dt.anchor.empty?
|
138
|
-
html_dt = "<a id=#{dt.anchor}></a>" + htmlify(dt.content)
|
139
|
-
else
|
140
|
-
html_dt = htmlify(dt.content)
|
141
|
-
end
|
142
|
-
if dd.content.empty?
|
143
|
-
html_dd = ''
|
144
|
-
else
|
145
|
-
html_dd = "<p>#{htmlify(dd.content)}</p>"
|
146
|
-
end
|
147
|
-
html_dd += dd.blocks.map{|block| block.render}.join
|
148
|
-
|
149
|
-
[html_dt, html_dd]
|
150
|
-
end
|
151
|
-
when :oblock, :quote
|
156
|
+
when :preamble, :oblock, :example, :sidebar
|
152
157
|
blocks.map{|block| block.render}.join
|
153
|
-
when :
|
158
|
+
when :colist
|
154
159
|
@buffer.map do |li|
|
155
|
-
htmlify(li.
|
156
|
-
end
|
157
|
-
when :ulist
|
158
|
-
@buffer.map do |element|
|
159
|
-
if element.is_a? Asciidoctor::ListItem
|
160
|
-
element.content = sub_attributes(element.content)
|
161
|
-
end
|
162
|
-
# TODO - not sure why tests work the same whether or not this is commented out.
|
163
|
-
# I think that I am likely not yet testing unordered list items with no block
|
164
|
-
# content. Still and all, it seems like this should be all done by list_item.render .
|
165
|
-
element.render # + element.blocks.map{|block| block.render}.join
|
160
|
+
htmlify(li.text) + li.blocks.map{|block| block.render}.join
|
166
161
|
end
|
162
|
+
# lists get iterated in template
|
163
|
+
# list items recurse into this block when their text and content methods are called
|
164
|
+
when :ulist, :olist, :dlist
|
165
|
+
@buffer
|
167
166
|
when :listing
|
168
|
-
@buffer.
|
167
|
+
sub_special_chars(@buffer.join).gsub(/<(\d+)>/, '<b>\1</b>')
|
169
168
|
when :literal
|
170
|
-
|
171
|
-
when :verse
|
172
|
-
|
169
|
+
sub_special_chars(@buffer.join)
|
170
|
+
when :quote, :verse, :admonition
|
171
|
+
if !@buffer.nil?
|
172
|
+
htmlify(sub_attributes(@buffer).map{ |l| l.strip }.join( "\n" ))
|
173
|
+
else
|
174
|
+
blocks.map{|block| block.render}.join
|
175
|
+
end
|
173
176
|
else
|
174
177
|
lines = sub_attributes(@buffer).map do |line|
|
175
178
|
line.strip
|
@@ -195,9 +198,9 @@ class Asciidoctor::Block
|
|
195
198
|
f = sub_special_chars(line)
|
196
199
|
# gsub! doesn't have lookbehind, so we have to capture and re-insert
|
197
200
|
f = f.gsub(/ (^|[^\\]) \{ (\w([\w\-_]+)?\w) \} /x) do
|
198
|
-
if self.document.
|
199
|
-
# Substitute from user
|
200
|
-
$1 + self.document.
|
201
|
+
if self.document.attributes.has_key?($2)
|
202
|
+
# Substitute from user attributes first
|
203
|
+
$1 + self.document.attributes[$2]
|
201
204
|
elsif Asciidoctor::INTRINSICS.has_key?($2)
|
202
205
|
# Then do intrinsics
|
203
206
|
$1 + Asciidoctor::INTRINSICS[$2]
|
@@ -215,7 +218,7 @@ class Asciidoctor::Block
|
|
215
218
|
Asciidoctor.debug "#{__method__} -> Processed line: #{f}"
|
216
219
|
f
|
217
220
|
end
|
218
|
-
Asciidoctor.debug "#{__method__} -> result looks like #{result.inspect}"
|
221
|
+
#Asciidoctor.debug "#{__method__} -> result looks like #{result.inspect}"
|
219
222
|
result.reject! {|l| l =~ /\{ZZZZZ\}/}
|
220
223
|
|
221
224
|
if return_string
|
@@ -242,7 +245,7 @@ class Asciidoctor::Block
|
|
242
245
|
end
|
243
246
|
end
|
244
247
|
end
|
245
|
-
Asciidoctor.debug "#{__method__} -> result looks like #{result.inspect}"
|
248
|
+
#Asciidoctor.debug "#{__method__} -> result looks like #{result.inspect}"
|
246
249
|
result.reject! {|l| l =~ /\{ZZZZZ\}/}
|
247
250
|
|
248
251
|
if return_string
|
@@ -251,6 +254,20 @@ class Asciidoctor::Block
|
|
251
254
|
result
|
252
255
|
end
|
253
256
|
|
257
|
+
# Public: Append a sub-block to this section block
|
258
|
+
#
|
259
|
+
# block - The new sub-block.
|
260
|
+
#
|
261
|
+
# block = Block.new(parent, :preamble)
|
262
|
+
#
|
263
|
+
# block << Block.new(block, :paragraph, 'p1')
|
264
|
+
# block << Block.new(block, :paragraph, 'p2')
|
265
|
+
# block.blocks
|
266
|
+
# => ["p1", "p2"]
|
267
|
+
def <<(block)
|
268
|
+
@blocks << block
|
269
|
+
end
|
270
|
+
|
254
271
|
private
|
255
272
|
|
256
273
|
# Private: Return a String HTML version of the source string, with
|
@@ -284,7 +301,7 @@ class Asciidoctor::Block
|
|
284
301
|
end
|
285
302
|
|
286
303
|
html.gsub!(Asciidoctor::REGEXP[:biblio], '<a name="\1">[\1]</a>')
|
287
|
-
html.gsub!(Asciidoctor::REGEXP[:ruler],
|
304
|
+
html.gsub!(Asciidoctor::REGEXP[:ruler], "<hr>\n")
|
288
305
|
html.gsub!(/``([^`']*)''/m, '“\1”')
|
289
306
|
html.gsub!(/(?:\s|^)`([^`']*)'/m, '‘\1’')
|
290
307
|
|