asciidoctor 0.0.1 → 0.0.2
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/LICENSE +1 -1
- data/README.md +136 -55
- data/asciidoctor.gemspec +10 -4
- data/lib/asciidoctor.rb +33 -7
- data/lib/asciidoctor/block.rb +161 -24
- data/lib/asciidoctor/debug.rb +12 -1
- data/lib/asciidoctor/document.rb +31 -630
- data/lib/asciidoctor/lexer.rb +654 -0
- data/lib/asciidoctor/list_item.rb +30 -0
- data/lib/asciidoctor/reader.rb +236 -0
- data/lib/asciidoctor/render_templates.rb +3 -3
- data/lib/asciidoctor/renderer.rb +22 -2
- data/lib/asciidoctor/version.rb +1 -1
- data/test/attributes_test.rb +88 -0
- data/test/document_test.rb +2 -8
- data/test/lexer_test.rb +12 -0
- data/test/list_elements_test.rb +1 -1
- data/test/reader_test.rb +56 -0
- data/test/test_helper.rb +7 -2
- data/test/text_test.rb +26 -20
- metadata +113 -95
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,69 +1,150 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
Asciidoctor
|
2
|
+
===========
|
3
3
|
|
4
|
-
|
4
|
+
Asciidoctor is a pure-ruby processor for turning
|
5
|
+
[Asciidoc](http://www.methods.co.nz/asciidoc/index.html) documents
|
6
|
+
into HTML (and, eventually, other formats perhaps).
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
RakeGem is here to make your life awesome!
|
8
|
+
Currently, asciidoctor uses some simple built-in ERB templates to
|
9
|
+
style the output in a way tht roughly matches the default HTML output
|
10
|
+
of the native Python processor.
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
a gem, and release your library and gem to the world.
|
12
|
+
Asciidoctor currently works with Ruby 1.8.7 and 1.9.3, though I don't
|
13
|
+
know of any reason it shouldn't work with more exotic Ruby versions,
|
14
|
+
and would welcome help in testing that out.
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
with your system without too much editing.
|
16
|
+
The initial code on which asciidoctor is based was from the Git SCM
|
17
|
+
site repo, [gitscm-next](https://github.com/github/gitscm-next).
|
19
18
|
|
20
|
-
|
21
|
-
[Sinatra](http://github.com/sinatra/sinatra) project.
|
19
|
+
# Installation
|
22
20
|
|
23
|
-
|
21
|
+
NOTE: This gem is very immature, and as yet only supports a small
|
22
|
+
subset of Asciidoc features. Thus, you should only use it if you have
|
23
|
+
a high tolerance for bugs, failures, and generally bad and intemperate
|
24
|
+
behavior.
|
24
25
|
|
25
|
-
|
26
|
-
with these files and edit a few lines to make them fit into your library. If
|
27
|
-
you have an existing project, you'll probably want to take the RakeGem
|
28
|
-
versions and copy any custom stuff from your existing Rakefile and gemspec
|
29
|
-
into them. As long as you're careful, the rake tasks should keep working.
|
26
|
+
To install the gem:
|
30
27
|
|
31
|
-
|
28
|
+
gem install 'asciidoctor'
|
32
29
|
|
33
|
-
|
34
|
-
assumptions or modify the rake tasks to work with your setup.
|
30
|
+
Or if you prefer bundler:
|
35
31
|
|
36
|
-
|
37
|
-
library) that contains a version line. It should look something like this:
|
32
|
+
bundle install 'asciidoctor'
|
38
33
|
|
39
|
-
|
40
|
-
VERSION = '0.1.0'
|
41
|
-
end
|
42
|
-
|
43
|
-
It is important that you use the constant `VERSION` and that it appear on a
|
44
|
-
line by itself.
|
45
|
-
|
46
|
-
# UPDATING THE VERSION
|
47
|
-
|
48
|
-
In order to make a new release, you'll want to update the version. With
|
49
|
-
RakeGem, you only need to do that in the `lib/NAME.rb` file. Everything else
|
50
|
-
will use this find the canonical version of the library.
|
34
|
+
# Usage
|
51
35
|
|
52
|
-
|
36
|
+
To render a file of Asciidoc-marked-up text to html
|
53
37
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
place it in the `pkg` directory.
|
61
|
-
|
62
|
-
`rake release` will update your gemspec, build your gem, make a commit with
|
63
|
-
the message `Release 0.1.0` (with the correct version, obviously), tag the
|
64
|
-
commit with `v0.1.0` (again with the correct version), and push the `master`
|
65
|
-
branch and new tag to `origin`.
|
38
|
+
lines = File.readlines("your_file.asc")
|
39
|
+
doc = Asciidoctor::Document.new(lines)
|
40
|
+
html = doc.render
|
41
|
+
File.open("your_file.html", "w+") do |file|
|
42
|
+
file.puts html
|
43
|
+
end
|
66
44
|
|
67
|
-
|
68
|
-
|
69
|
-
|
45
|
+
Render an Asciidoc-formatted string
|
46
|
+
|
47
|
+
doc = Asciidoctor::Document.new("*This* is it.")
|
48
|
+
puts doc.render
|
49
|
+
|
50
|
+
Asciidoctor allows you to override the default template used to render
|
51
|
+
almost any individual Asciidoc elements. If you provide a directory of
|
52
|
+
[Tilt](https://github.com/rtomayko/tilt)-compatible templates, named
|
53
|
+
in a way Asciidoctor can figure out which template goes with which
|
54
|
+
element, Asciidoctor will use the templates in this directory instead
|
55
|
+
of its built-in templates for any elements for which it finds a
|
56
|
+
matching template. It will use its default templates for everything
|
57
|
+
else.
|
58
|
+
|
59
|
+
doc = Asciidoctor::Document.new("*This* is it.", :template_dir => 'templates')
|
60
|
+
puts doc.render
|
61
|
+
|
62
|
+
The Document and Section templates should begin with `document.` and
|
63
|
+
`section.`, respectively. The file extension will depend on which
|
64
|
+
Tilt-compatible format you've chosen. For ERB, they would be
|
65
|
+
`document.html.erb` and `section.html.erb`, for instance.
|
66
|
+
|
67
|
+
Specific elements, like a Paragraph or Anchor, would begin with
|
68
|
+
`section_<element>.`. So to override the default Paragraph template
|
69
|
+
with an ERB template you'd put a file called
|
70
|
+
`section_paragraph.html.erb` in the template directory you pass in to
|
71
|
+
`Document.new`.
|
72
|
+
|
73
|
+
For more usage examples, see the test suite.
|
74
|
+
|
75
|
+
## Contributing
|
76
|
+
In the spirit of [free software][free-sw], **everyone** is encouraged to help
|
77
|
+
improve this project.
|
78
|
+
|
79
|
+
[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
|
80
|
+
|
81
|
+
Here are some ways *you* can contribute:
|
82
|
+
|
83
|
+
* by using alpha, beta, and prerelease versions
|
84
|
+
* by reporting bugs
|
85
|
+
* by suggesting new features
|
86
|
+
* by writing or editing documentation
|
87
|
+
* by writing specifications
|
88
|
+
* by writing code (**no patch is too small**: fix typos, add comments, clean up
|
89
|
+
inconsistent whitespace)
|
90
|
+
* by refactoring code
|
91
|
+
* by fixing [issues][]
|
92
|
+
* by reviewing patches
|
93
|
+
|
94
|
+
[issues]: https://github.com/erebor/asciidoctor/issues
|
95
|
+
|
96
|
+
## Submitting an Issue
|
97
|
+
We use the [GitHub issue tracker][issues] to track bugs and
|
98
|
+
features. Before submitting a bug report or feature request, check to
|
99
|
+
make sure it hasn't already been submitted. When submitting a bug
|
100
|
+
report, please include a [Gist][] that includes any details that may
|
101
|
+
help reproduce the bug, including your gem version, Ruby version, and
|
102
|
+
operating system.
|
103
|
+
|
104
|
+
Most importantly, since asciidoctor is a text processor, reproducing
|
105
|
+
most bugs requires that we have some snippet of text on which
|
106
|
+
asciidoctor exhibits the bad behavior.
|
107
|
+
|
108
|
+
An ideal bug report would include a pull request with failing
|
109
|
+
specs.
|
110
|
+
|
111
|
+
[gist]: https://gist.github.com/
|
112
|
+
|
113
|
+
## Submitting a Pull Request
|
114
|
+
1. [Fork the repository.][fork]
|
115
|
+
2. [Create a topic branch.][branch]
|
116
|
+
3. Add tests for your unimplemented feature or bug fix.
|
117
|
+
4. Run `bundle exec rake`. If your tests pass, return to step 3.
|
118
|
+
5. Implement your feature or bug fix.
|
119
|
+
6. Run `bundle exec rake`. If your tests fail, return to step 5.
|
120
|
+
7. Add documentation for your feature or bug fix.
|
121
|
+
8. If your changes are not 100% documented, go back to step 7.
|
122
|
+
9. Add, commit, and push your changes.
|
123
|
+
10. [Submit a pull request.][pr]
|
124
|
+
|
125
|
+
[fork]: http://help.github.com/fork-a-repo/
|
126
|
+
[branch]: http://learn.github.com/p/branching.html
|
127
|
+
[pr]: http://help.github.com/send-pull-requests/
|
128
|
+
|
129
|
+
## Supported Ruby Versions
|
130
|
+
This library aims to support the following Ruby implementations:
|
131
|
+
|
132
|
+
* Ruby 1.8.7
|
133
|
+
* Ruby 1.9.3
|
134
|
+
|
135
|
+
If something doesn't work on one of these interpreters, it should be
|
136
|
+
considered a bug.
|
137
|
+
|
138
|
+
If you would like this library to support another Ruby version, you
|
139
|
+
may volunteer to be a maintainer. Being a maintainer entails making
|
140
|
+
sure all tests run and pass on that implementation. When something
|
141
|
+
breaks on your implementation, you will be personally responsible for
|
142
|
+
providing patches in a timely fashion. If critical issues for a
|
143
|
+
particular implementation exist at the time of a major release,
|
144
|
+
support for that Ruby version may be dropped.
|
145
|
+
|
146
|
+
## Copyright
|
147
|
+
Copyright (c) 2012 Ryan Waldron.
|
148
|
+
See [LICENSE][] for details.
|
149
|
+
|
150
|
+
[license]: https://github.com/erebor/asciidoctor/blob/master/LICENSE
|
data/asciidoctor.gemspec
CHANGED
@@ -13,14 +13,14 @@ 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.2'
|
17
|
+
s.date = '2012-08-03'
|
18
18
|
s.rubyforge_project = 'asciidoctor'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
21
21
|
## as you like.
|
22
22
|
s.summary = "Pure Ruby Asciidoc to HTML rendering."
|
23
|
-
s.description = "
|
23
|
+
s.description = "A pure Ruby processor to turn Asciidoc-formatted documents into HTML (and, eventually, other formats perhaps)."
|
24
24
|
|
25
25
|
## List the primary authors. If there are a bunch of authors, it's probably
|
26
26
|
## better to set the email to an email list or something. If you don't have
|
@@ -44,13 +44,14 @@ Gem::Specification.new do |s|
|
|
44
44
|
## List your runtime dependencies here. Runtime dependencies are those
|
45
45
|
## that are needed for an end user to actually USE your code.
|
46
46
|
s.add_dependency('json')
|
47
|
-
s.add_dependency('
|
47
|
+
s.add_dependency('tilt')
|
48
48
|
|
49
49
|
## List your development dependencies here. Development dependencies are
|
50
50
|
## those that are only needed during development
|
51
51
|
s.add_development_dependency('mocha')
|
52
52
|
s.add_development_dependency('nokogiri')
|
53
53
|
s.add_development_dependency('htmlentities')
|
54
|
+
s.add_development_dependency('pending')
|
54
55
|
|
55
56
|
## Leave this section as-is. It will be automatically generated from the
|
56
57
|
## contents of your Git repository via the gemspec task. DO NOT REMOVE
|
@@ -67,21 +68,26 @@ Gem::Specification.new do |s|
|
|
67
68
|
lib/asciidoctor/debug.rb
|
68
69
|
lib/asciidoctor/document.rb
|
69
70
|
lib/asciidoctor/errors.rb
|
71
|
+
lib/asciidoctor/lexer.rb
|
70
72
|
lib/asciidoctor/list_item.rb
|
73
|
+
lib/asciidoctor/reader.rb
|
71
74
|
lib/asciidoctor/render_templates.rb
|
72
75
|
lib/asciidoctor/renderer.rb
|
73
76
|
lib/asciidoctor/section.rb
|
74
77
|
lib/asciidoctor/string.rb
|
75
78
|
lib/asciidoctor/version.rb
|
76
79
|
noof.rb
|
80
|
+
test/attributes_test.rb
|
77
81
|
test/document_test.rb
|
78
82
|
test/fixtures/asciidoc.txt
|
79
83
|
test/fixtures/asciidoc_index.txt
|
80
84
|
test/fixtures/ascshort.txt
|
81
85
|
test/fixtures/list_elements.asciidoc
|
82
86
|
test/headers_test.rb
|
87
|
+
test/lexer_test.rb
|
83
88
|
test/list_elements_test.rb
|
84
89
|
test/paragraphs_test.rb
|
90
|
+
test/reader_test.rb
|
85
91
|
test/test_helper.rb
|
86
92
|
test/text_test.rb
|
87
93
|
]
|
data/lib/asciidoctor.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'cgi'
|
3
3
|
require 'erb'
|
4
|
+
require 'tilt'
|
4
5
|
|
5
6
|
$:.unshift(File.dirname(__FILE__))
|
6
7
|
$:.unshift(File.join(File.dirname(__FILE__), '..', 'vendor'))
|
@@ -40,6 +41,13 @@ module Asciidoctor
|
|
40
41
|
# Foowhatevs [[Bar]]
|
41
42
|
:anchor_embedded => /^(.*)\[\[([^\]]+)\]\]\s*$/,
|
42
43
|
|
44
|
+
# + Attribute values treat lines ending with ' +' as a continuation,
|
45
|
+
# not a line-break as elsewhere in the document, where this is
|
46
|
+
# a forced line break. This should be the same regexp as :line_break,
|
47
|
+
# below, but it gets its own entry because readability ftw, even
|
48
|
+
# though repeating regexps ftl.
|
49
|
+
:attr_continue => /(.*)(?:^|\s)\+$/,
|
50
|
+
|
43
51
|
# [[[Foo]]] (does not suffer quite the same malady as :anchor, but almost. Allows [ but not ] in internal capture
|
44
52
|
:biblio => /\[\[\[([^\]]+)\]\]\]/,
|
45
53
|
|
@@ -52,11 +60,6 @@ module Asciidoctor
|
|
52
60
|
# // (and then whatever)
|
53
61
|
:comment => /^\/\/\s/,
|
54
62
|
|
55
|
-
# + Note that Asciidoc appears to allow continuations using + at
|
56
|
-
# the end of the previous line and indenting
|
57
|
-
# the following line (as in :lit_par)
|
58
|
-
:continue => /^\+\s*$/,
|
59
|
-
|
60
63
|
# foo:: || foo;;
|
61
64
|
# Should be followed by a definition line, e.g.,
|
62
65
|
# foo::
|
@@ -78,6 +81,23 @@ module Asciidoctor
|
|
78
81
|
# ====== || ------ || ~~~~~~ || ^^^^^^ || ++++++
|
79
82
|
:line => /^([=\-~^\+])+\s*$/,
|
80
83
|
|
84
|
+
# + From the Asciidoc User Guide: "A plus character preceded by at
|
85
|
+
# least one space character at the end of a non-blank line forces
|
86
|
+
# a line break. It generates a line break (br) tag for HTML outputs.
|
87
|
+
#
|
88
|
+
# This is the correct regexp to match what the User Guide actually
|
89
|
+
# says to do:
|
90
|
+
# :line_break => /^(.*(?:\S+)+.*)\s\+$/,
|
91
|
+
#
|
92
|
+
# But the regexp we're using (below), is what asciidoc *actually*
|
93
|
+
# does for HTML output, courtesy of the default html4.conf file (under
|
94
|
+
# the [replacements2] section).
|
95
|
+
#
|
96
|
+
# + (would not match because there's no space before +)
|
97
|
+
# + (would match and capture '')
|
98
|
+
# Foo + (would and capture 'Foo')
|
99
|
+
:line_break => /^(.*)\s\+$/,
|
100
|
+
|
81
101
|
# ----
|
82
102
|
:listing => /^\-{4,}\s*$/,
|
83
103
|
|
@@ -106,7 +126,7 @@ module Asciidoctor
|
|
106
126
|
# ____
|
107
127
|
:quote => /^_{4,}\s*$/,
|
108
128
|
|
109
|
-
#
|
129
|
+
# ''''
|
110
130
|
:ruler => /^'{3,}\s*$/,
|
111
131
|
|
112
132
|
# ****
|
@@ -120,7 +140,7 @@ module Asciidoctor
|
|
120
140
|
:title => /^\.([^\s\.].*)\s*$/,
|
121
141
|
|
122
142
|
# * Foo || - Foo
|
123
|
-
:ulist =>
|
143
|
+
:ulist => /^ \s* (- | \*{1,5}) \s+ (.*) $/x,
|
124
144
|
|
125
145
|
# [verse]
|
126
146
|
:verse => /^\[verse\]\s*$/
|
@@ -139,11 +159,17 @@ module Asciidoctor
|
|
139
159
|
'backtick' => '`'
|
140
160
|
)
|
141
161
|
|
162
|
+
HTML_ELEMENTS = {
|
163
|
+
'br-asciidoctor' => '<br/>'
|
164
|
+
}
|
165
|
+
|
142
166
|
require 'asciidoctor/block'
|
143
167
|
require 'asciidoctor/debug'
|
144
168
|
require 'asciidoctor/document'
|
145
169
|
require 'asciidoctor/errors'
|
170
|
+
require 'asciidoctor/lexer'
|
146
171
|
require 'asciidoctor/list_item'
|
172
|
+
require 'asciidoctor/reader'
|
147
173
|
require 'asciidoctor/render_templates'
|
148
174
|
require 'asciidoctor/renderer'
|
149
175
|
require 'asciidoctor/section'
|
data/lib/asciidoctor/block.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Examples
|
4
4
|
#
|
5
|
-
# block = Asciidoctor::Block.new(:paragraph, ["`This` is a <test>"])
|
5
|
+
# block = Asciidoctor::Block.new(document, :paragraph, ["`This` is a <test>"])
|
6
6
|
# block.content
|
7
7
|
# => ["<em>This</em> is a <test>"]
|
8
8
|
class Asciidoctor::Block
|
@@ -18,6 +18,10 @@ class Asciidoctor::Block
|
|
18
18
|
# Public: Get/Set the String section anchor name.
|
19
19
|
attr_accessor :anchor
|
20
20
|
|
21
|
+
# Public: Get/Set the Integer block level (for nested elements, like
|
22
|
+
# list elements).
|
23
|
+
attr_accessor :level
|
24
|
+
|
21
25
|
# Public: Get/Set the String block title.
|
22
26
|
attr_accessor :title
|
23
27
|
|
@@ -29,6 +33,10 @@ class Asciidoctor::Block
|
|
29
33
|
# parent - The parent Asciidoc Object.
|
30
34
|
# context - The Symbol context name for the type of content.
|
31
35
|
# buffer - The Array buffer of source data.
|
36
|
+
|
37
|
+
# TODO: Don't really need the parent, just the document (for access
|
38
|
+
# both to its renderer, as well as its references and other defined
|
39
|
+
# elements). Would probably be better to pass in just the document.
|
32
40
|
def initialize(parent, context, buffer=nil)
|
33
41
|
@parent = parent
|
34
42
|
@context = context
|
@@ -39,13 +47,14 @@ class Asciidoctor::Block
|
|
39
47
|
|
40
48
|
# Public: Get the Asciidoctor::Document instance to which this Block belongs
|
41
49
|
def document
|
42
|
-
|
50
|
+
return @document if @document
|
51
|
+
@document = (@parent.is_a?(Asciidoctor::Document) ? @parent : @parent.document)
|
43
52
|
end
|
44
53
|
|
45
54
|
# Public: Get the Asciidoctor::Renderer instance being used for the ancestor
|
46
55
|
# Asciidoctor::Document instance.
|
47
56
|
def renderer
|
48
|
-
|
57
|
+
document.renderer
|
49
58
|
end
|
50
59
|
|
51
60
|
# Public: Get the rendered String content for this Block. If the block
|
@@ -59,21 +68,69 @@ class Asciidoctor::Block
|
|
59
68
|
renderer.render("section_#{context}", self)
|
60
69
|
end
|
61
70
|
|
71
|
+
def splain(parent_level = 0)
|
72
|
+
parent_level += 1
|
73
|
+
Asciidoctor.puts_indented(parent_level, "Block title: #{title}") unless self.title.nil?
|
74
|
+
Asciidoctor.puts_indented(parent_level, "Block anchor: #{anchor}") unless self.anchor.nil?
|
75
|
+
Asciidoctor.puts_indented(parent_level, "Block caption: #{caption}") unless self.caption.nil?
|
76
|
+
Asciidoctor.puts_indented(parent_level, "Block level: #{level}") unless self.level.nil?
|
77
|
+
Asciidoctor.puts_indented(parent_level, "Block context: #{context}") unless self.context.nil?
|
78
|
+
|
79
|
+
Asciidoctor.puts_indented(parent_level, "Blocks: #{@blocks.count}")
|
80
|
+
|
81
|
+
if buffer.is_a? Enumerable
|
82
|
+
buffer.each_with_index do |buf, i|
|
83
|
+
Asciidoctor.puts_indented(parent_level, "v" * (60 - parent_level*2))
|
84
|
+
Asciidoctor.puts_indented(parent_level, "Buffer ##{i} is a #{buf.class}")
|
85
|
+
Asciidoctor.puts_indented(parent_level, "Name is #{buf.name rescue 'n/a'}")
|
86
|
+
|
87
|
+
if buf.respond_to? :splain
|
88
|
+
buf.splain(parent_level)
|
89
|
+
else
|
90
|
+
Asciidoctor.puts_indented(parent_level, "Buffer: #{buf}")
|
91
|
+
end
|
92
|
+
Asciidoctor.puts_indented(parent_level, "^" * (60 - parent_level*2))
|
93
|
+
end
|
94
|
+
else
|
95
|
+
if buffer.respond_to? :splain
|
96
|
+
buffer.splain(parent_level)
|
97
|
+
else
|
98
|
+
Asciidoctor.puts_indented(parent_level, "Buffer: #{@buffer}")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
@blocks.each_with_index do |block, i|
|
103
|
+
Asciidoctor.puts_indented(parent_level, "v" * (60 - parent_level*2))
|
104
|
+
Asciidoctor.puts_indented(parent_level, "Block ##{i} is a #{block.class}")
|
105
|
+
Asciidoctor.puts_indented(parent_level, "Name is #{block.name rescue 'n/a'}")
|
106
|
+
|
107
|
+
block.splain(parent_level) if block.respond_to? :splain
|
108
|
+
Asciidoctor.puts_indented(parent_level, "^" * (60 - parent_level*2))
|
109
|
+
end
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
|
62
113
|
# Public: Get an HTML-ified version of the source buffer, with special
|
63
114
|
# Asciidoc characters and entities converted to their HTML equivalents.
|
64
115
|
#
|
65
116
|
# Examples
|
66
117
|
#
|
67
|
-
#
|
118
|
+
# doc = Asciidoctor::Document.new([])
|
119
|
+
# block = Asciidoctor::Block.new(doc, :paragraph,
|
120
|
+
# ['`This` is what happens when you <meet> a stranger in the <alps>!'])
|
68
121
|
# block.content
|
69
122
|
# => ["<em>This</em> is what happens when you <meet> a stranger in the <alps>!"]
|
70
123
|
#
|
71
124
|
# TODO:
|
72
|
-
# * forced line breaks
|
125
|
+
# * forced line breaks (partly done, at least in regular paragraphs)
|
73
126
|
# * bold, mono
|
74
127
|
# * double/single quotes
|
75
128
|
# * super/sub script
|
76
129
|
def content
|
130
|
+
|
131
|
+
Asciidoctor.debug "For the record, buffer is:"
|
132
|
+
Asciidoctor.debug @buffer.inspect
|
133
|
+
|
77
134
|
case @context
|
78
135
|
when :dlist
|
79
136
|
@buffer.map do |dt, dd|
|
@@ -93,21 +150,106 @@ class Asciidoctor::Block
|
|
93
150
|
end
|
94
151
|
when :oblock, :quote
|
95
152
|
blocks.map{|block| block.render}.join
|
96
|
-
when :olist, :
|
153
|
+
when :olist, :colist
|
97
154
|
@buffer.map do |li|
|
98
155
|
htmlify(li.content) + li.blocks.map{|block| block.render}.join
|
99
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
|
166
|
+
end
|
100
167
|
when :listing
|
101
168
|
@buffer.map{|l| CGI.escapeHTML(l).gsub(/(<\d+>)/,'<b>\1</b>')}.join
|
102
169
|
when :literal
|
103
170
|
htmlify( @buffer.join.gsub( '*', '{asterisk}' ).gsub( '\'', '{apostrophe}' ))
|
104
171
|
when :verse
|
105
|
-
htmlify( @buffer.map{ |l| l.strip }.join( "\n" ) )
|
172
|
+
htmlify( sub_attributes(@buffer).map{ |l| l.strip }.join( "\n" ) )
|
106
173
|
else
|
107
|
-
|
174
|
+
lines = sub_attributes(@buffer).map do |line|
|
175
|
+
line.strip
|
176
|
+
line.gsub(Asciidoctor::REGEXP[:line_break], '\1{br-asciidoctor}')
|
177
|
+
end
|
178
|
+
lines = htmlify( lines.join )
|
179
|
+
sub_html_attributes(lines) # got to clean up the br-asciidoctor line-break
|
108
180
|
end
|
109
181
|
end
|
110
182
|
|
183
|
+
# Attribute substitution
|
184
|
+
#
|
185
|
+
# TODO: Tom all the docs
|
186
|
+
def sub_attributes(lines)
|
187
|
+
Asciidoctor.debug "Entering #{__method__} from #{caller[0]}"
|
188
|
+
if lines.is_a? String
|
189
|
+
return_string = true
|
190
|
+
lines = Array(lines)
|
191
|
+
end
|
192
|
+
|
193
|
+
result = lines.map do |line|
|
194
|
+
Asciidoctor.debug "#{__method__} -> Processing line: #{line}"
|
195
|
+
# gsub! doesn't have lookbehind, so we have to capture and re-insert
|
196
|
+
f = line.gsub(/ (^|[^\\]) \{ (\w[\w\-_]+\w) \} /x) do
|
197
|
+
if self.document.defines.has_key?($2)
|
198
|
+
# Substitute from user defines first
|
199
|
+
$1 + self.document.defines[$2]
|
200
|
+
elsif Asciidoctor::INTRINSICS.has_key?($2)
|
201
|
+
# Then do intrinsics
|
202
|
+
$1 + Asciidoctor::INTRINSICS[$2]
|
203
|
+
elsif Asciidoctor::HTML_ELEMENTS.has_key?($2)
|
204
|
+
$1 + Asciidoctor::HTML_ELEMENTS[$2]
|
205
|
+
else
|
206
|
+
Asciidoctor.debug "Bailing on key: #{$2}"
|
207
|
+
# delete the line if it has a bad attribute
|
208
|
+
# TODO: According to AsciiDoc, we're supposed to delete any line
|
209
|
+
# containing a bad attribute. Eek! Can't do that here via gsub!.
|
210
|
+
# (See `subs_attrs` function in asciidoc.py for many gory details.)
|
211
|
+
"{ZZZZZ}"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
Asciidoctor.debug "#{__method__} -> Processed line: #{f}"
|
215
|
+
f
|
216
|
+
end
|
217
|
+
Asciidoctor.debug "#{__method__} -> result looks like #{result.inspect}"
|
218
|
+
result.reject! {|l| l =~ /\{ZZZZZ\}/}
|
219
|
+
|
220
|
+
if return_string
|
221
|
+
result = result.join
|
222
|
+
end
|
223
|
+
result
|
224
|
+
end
|
225
|
+
|
226
|
+
def sub_html_attributes(lines)
|
227
|
+
Asciidoctor.debug "Entering #{__method__} from #{caller[0]}"
|
228
|
+
if lines.is_a? String
|
229
|
+
return_string = true
|
230
|
+
lines = Array(lines)
|
231
|
+
end
|
232
|
+
|
233
|
+
result = lines.map do |line|
|
234
|
+
Asciidoctor.debug "#{__method__} -> Processing line: #{line}"
|
235
|
+
# gsub! doesn't have lookbehind, so we have to capture and re-insert
|
236
|
+
line.gsub(/ (^|[^\\]) \{ (\w[\w\-_]+\w) \} /x) do
|
237
|
+
if Asciidoctor::HTML_ELEMENTS.has_key?($2)
|
238
|
+
$1 + Asciidoctor::HTML_ELEMENTS[$2]
|
239
|
+
else
|
240
|
+
$1 + "{#{$2}}"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
Asciidoctor.debug "#{__method__} -> result looks like #{result.inspect}"
|
245
|
+
result.reject! {|l| l =~ /\{ZZZZZ\}/}
|
246
|
+
|
247
|
+
if return_string
|
248
|
+
result = result.join
|
249
|
+
end
|
250
|
+
result
|
251
|
+
end
|
252
|
+
|
111
253
|
private
|
112
254
|
|
113
255
|
# Private: Return a String HTML version of the source string, with
|
@@ -143,8 +285,16 @@ class Asciidoctor::Block
|
|
143
285
|
html = CGI.escapeHTML(html)
|
144
286
|
html.gsub!(Asciidoctor::REGEXP[:biblio], '<a name="\1">[\1]</a>')
|
145
287
|
html.gsub!(Asciidoctor::REGEXP[:ruler], '<hr>\n')
|
146
|
-
html.gsub!(/``(
|
147
|
-
html.gsub!(
|
288
|
+
html.gsub!(/``([^`']*)''/m, '“\1”')
|
289
|
+
html.gsub!(/(?:\s|^)`([^`']*)'/m, '‘\1’')
|
290
|
+
|
291
|
+
# TODO: This text thus quoted is supposed to be rendered as an
|
292
|
+
# "inline literal passthrough", meaning that it is rendered
|
293
|
+
# in a monospace font, but also doesn't go through any further
|
294
|
+
# text substitution, except for special character substitution.
|
295
|
+
# So we need to technically pull this text out, sha it and store
|
296
|
+
# a marker and replace it after the other gsub!s are done in here.
|
297
|
+
# See: http://www.methods.co.nz/asciidoc/userguide.html#X80
|
148
298
|
html.gsub!(/`([^`]+)`/m) { "<tt>#{$1.gsub( '*', '{asterisk}' ).gsub( '\'', '{apostrophe}' )}</tt>" }
|
149
299
|
html.gsub!(/([\s\W])#(.+?)#([\s\W])/, '\1\2\3')
|
150
300
|
|
@@ -164,23 +314,10 @@ class Asciidoctor::Block
|
|
164
314
|
html.gsub!(/([\s\W])\^([^\^]+)\^([\s\W])/m, '\1<sup>\2</sup>\3')
|
165
315
|
html.gsub!(/([\s\W])\~([^\~]+)\~([\s\W])/m, '\1<sub>\2</sub>\3')
|
166
316
|
|
167
|
-
# Don't have lookbehind so have to capture and re-insert
|
168
|
-
html.gsub!(/(^|[^\\])\{(\w[\w\-]+\w)\}/) do
|
169
|
-
if self.document.defines.has_key?($2)
|
170
|
-
# Substitute from user defines first
|
171
|
-
$1 + self.document.defines[$2]
|
172
|
-
elsif Asciidoctor::INTRINSICS.has_key?($2)
|
173
|
-
# Then do intrinsics
|
174
|
-
$1 + Asciidoctor::INTRINSICS[$2]
|
175
|
-
else
|
176
|
-
# leave everything else alone
|
177
|
-
"#{$1}{#{$2}}"
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
317
|
html.gsub!(/\\([\{\}\-])/, '\1')
|
182
318
|
html.gsub!(/linkgit:([^\]]+)\[(\d+)\]/, '<a href="\1.html">\1(\2)</a>')
|
183
319
|
html.gsub!(/link:([^\[]+)(\[+[^\]]*\]+)/ ) { "<a href=\"#{$1}\">#{$2.gsub( /(^\[|\]$)/,'' )}</a>" }
|
320
|
+
html.gsub!(Asciidoctor::REGEXP[:line_break], '\1<br/>')
|
184
321
|
html
|
185
322
|
end
|
186
323
|
end
|