asciidoctor 0.0.9 → 0.1.0
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 +163 -41
- data/Rakefile +3 -1
- data/asciidoctor.gemspec +13 -5
- data/bin/asciidoctor +6 -3
- data/bin/asciidoctor-safe +13 -0
- data/lib/asciidoctor.rb +237 -26
- data/lib/asciidoctor/abstract_node.rb +27 -17
- data/lib/asciidoctor/attribute_list.rb +6 -0
- data/lib/asciidoctor/backends/base_template.rb +3 -4
- data/lib/asciidoctor/backends/docbook45.rb +114 -55
- data/lib/asciidoctor/backends/html5.rb +173 -104
- data/lib/asciidoctor/cli/invoker.rb +105 -0
- data/lib/asciidoctor/cli/options.rb +146 -0
- data/lib/asciidoctor/document.rb +135 -35
- data/lib/asciidoctor/lexer.rb +86 -33
- data/lib/asciidoctor/list_item.rb +2 -2
- data/lib/asciidoctor/reader.rb +6 -7
- data/lib/asciidoctor/section.rb +17 -5
- data/lib/asciidoctor/substituters.rb +216 -97
- data/lib/asciidoctor/table.rb +9 -2
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +212 -0
- data/man/asciidoctor.ad +156 -0
- data/test/attributes_test.rb +108 -5
- data/test/blocks_test.rb +102 -15
- data/test/document_test.rb +214 -3
- data/test/fixtures/encoding.asciidoc +4 -0
- data/test/fixtures/sample.asciidoc +26 -0
- data/test/invoker_test.rb +254 -0
- data/test/lexer_test.rb +53 -0
- data/test/links_test.rb +30 -0
- data/test/lists_test.rb +648 -9
- data/test/options_test.rb +68 -0
- data/test/paragraphs_test.rb +65 -1
- data/test/reader_test.rb +18 -4
- data/test/{headers_test.rb → sections_test.rb} +237 -0
- data/test/substitutions_test.rb +247 -5
- data/test/tables_test.rb +22 -4
- data/test/test_helper.rb +47 -3
- data/test/text_test.rb +20 -4
- metadata +34 -6
- data/noof.rb +0 -16
data/README.asciidoc
CHANGED
@@ -1,46 +1,53 @@
|
|
1
|
-
[float]
|
2
1
|
Asciidoctor
|
3
2
|
===========
|
4
|
-
:asciidoctor: http://
|
5
|
-
:
|
3
|
+
:asciidoctor: http://asciidoctor.org
|
4
|
+
:asciidoctor-source: http://github.com/asciidoctor/asciidoctor
|
5
|
+
:asciidoc: http://asciidoc.org
|
6
6
|
:gitscm-next: https://github.com/github/gitscm-next
|
7
|
-
:
|
8
|
-
:templates: https://github.com/
|
7
|
+
:asciidoctor-seed: https://github.com/github/gitscm-next/commits/master/lib/asciidoc.rb
|
8
|
+
:templates: https://github.com/asciidoctor/asciidoctor/blob/master/lib/asciidoctor/backends
|
9
9
|
:tilt: https://github.com/rtomayko/tilt
|
10
10
|
:freesoftware: http://www.fsf.org/licensing/essays/free-sw.html
|
11
|
-
:issues: https://github.com/
|
11
|
+
:issues: https://github.com/asciidoctor/asciidoctor/issues
|
12
12
|
:gist: https://gist.github.com
|
13
13
|
:fork: http://help.github.com/fork-a-repo/
|
14
14
|
:branch: http://learn.github.com/p/branching.html
|
15
15
|
:pr: http://help.github.com/send-pull-requests/
|
16
|
-
:license: https://github.com/
|
16
|
+
:license: https://github.com/asciidoctor/asciidoctor/blob/master/LICENSE
|
17
|
+
:idprefix:
|
17
18
|
|
18
|
-
{asciidoctor}[Asciidoctor] is a pure
|
19
|
-
{asciidoc}[AsciiDoc]
|
20
|
-
other formats
|
19
|
+
{asciidoctor}[Asciidoctor] is a pure Ruby processor for converting
|
20
|
+
{asciidoc}[AsciiDoc] source files and strings into HTML 5, DocBook 4.5
|
21
|
+
and other formats. It's
|
22
|
+
http://rubygems.org/gems/asciidoctor[published as a RubyGem] and is
|
23
|
+
available under the MIT open source license.
|
21
24
|
|
22
|
-
image::https://travis-ci.org/
|
25
|
+
image::https://travis-ci.org/asciidoctor/asciidoctor.png?branch=master["Build Status", link="https://travis-ci.org/asciidoctor/asciidoctor"]
|
23
26
|
|
24
|
-
Asciidoctor uses
|
25
|
-
|
26
|
-
Python processor. You can
|
27
|
-
{tilt}[Tilt]-compatible templates.
|
28
|
-
for more details.
|
27
|
+
Asciidoctor uses a set of built-in ERB templates to render the document
|
28
|
+
to HTML 5 or DocBook 4.5. We've matched the rendered output as close as
|
29
|
+
possible to the default output of the native Python processor. You can
|
30
|
+
override this behavior by providing {tilt}[Tilt]-compatible templates.
|
31
|
+
See the xref:usage[Usage section] for more details.
|
29
32
|
|
30
|
-
Asciidoctor currently works with Ruby 1.8.7
|
31
|
-
|
32
|
-
and would welcome help in
|
33
|
+
Asciidoctor currently works (read as 'tested') with Ruby 1.8.7, Ruby
|
34
|
+
1.9.3 and JRuby 1.7.2 (on Linux, Mac and Windows). We expect it will
|
35
|
+
work with other versions of Ruby as well and would welcome help in
|
36
|
+
testing it out.
|
33
37
|
|
34
|
-
The initial code from which Asciidoctor started
|
38
|
+
The initial code from which Asciidoctor started emerged from the
|
35
39
|
{gitscm-next}[Git SCM site repo]. Refer to commit history of
|
36
|
-
{
|
40
|
+
{asciidoctor-seed}[asciidoc.rb] to view the initial contributions and
|
41
|
+
individual contributors.
|
42
|
+
|
43
|
+
The source code can now be found in the {asciidoctor-source}[Asciidoctor
|
44
|
+
source repository] on GitHub.
|
37
45
|
|
38
46
|
== Installation
|
39
47
|
|
40
|
-
NOTE:
|
41
|
-
|
42
|
-
|
43
|
-
bad and intemperate behavior.
|
48
|
+
NOTE: We are working hard to make Asciidoctor a drop-in replacement for
|
49
|
+
AsciiDoc. We're very close, with nearly 600 tests that ensure
|
50
|
+
compatibility. The march is on towards full compliance and beyond.
|
44
51
|
|
45
52
|
To install the gem:
|
46
53
|
|
@@ -52,20 +59,91 @@ Or if you prefer bundler:
|
|
52
59
|
|
53
60
|
== Usage
|
54
61
|
|
55
|
-
|
62
|
+
Asciidoctor has both a command line interface (CLI) and an API. The
|
63
|
+
CLI is a drop-in replacement for the `asciidoc.py` command from the
|
64
|
+
python implementation. The API is intended for integration with other
|
65
|
+
software projects and is suitable for server-side applications, such
|
66
|
+
as Rails, Sinatra and GitHub.
|
67
|
+
|
68
|
+
=== Command line interface (CLI)
|
69
|
+
|
70
|
+
After installing the `asciidoctor` gem, the `asciidoctor` commandline
|
71
|
+
interface should be available on your PATH after installing the gem.
|
72
|
+
To invoke it, simply execute:
|
73
|
+
|
74
|
+
asciidoctor <asciidoc_file>
|
75
|
+
|
76
|
+
This will use the built-in defaults for options and create a new file
|
77
|
+
in the same directory as the input file, with the same base name, but
|
78
|
+
with the .html extention.
|
79
|
+
|
80
|
+
There are many other options available and full help is provided via:
|
81
|
+
|
82
|
+
asciidoctor --help
|
83
|
+
|
84
|
+
, or in the http://asciidoctor.org/man/asciidoctor[man page].
|
85
|
+
|
86
|
+
There is also an `asciidoctor-safe` command, which turns on safe mode
|
87
|
+
by default, preventing access to files outside the parent directory of
|
88
|
+
the source file. This mode is very similar to the safe mode of `asciidoc.py`.
|
89
|
+
|
90
|
+
=== Ruby API
|
91
|
+
|
92
|
+
To use Asciidoctor in your application, you first need to require the
|
93
|
+
gem:
|
94
|
+
|
95
|
+
require 'asciidoctor'
|
96
|
+
|
97
|
+
With that in place, you can start processing AsciiDoc documents.
|
98
|
+
|
99
|
+
.Loading a document
|
100
|
+
To parse a file into an `Asciidoctor::Document` object:
|
56
101
|
|
57
|
-
|
58
|
-
doc = Asciidoctor::Document.new(lines)
|
59
|
-
html = doc.render
|
60
|
-
File.open('your_file.html', 'w+') do |file|
|
61
|
-
file.puts html
|
62
|
-
end
|
102
|
+
doc = Asciidoctor.load_file('your_file.asciidoc')
|
63
103
|
|
104
|
+
You can get information about the document:
|
105
|
+
|
106
|
+
puts doc.doctitle
|
107
|
+
puts doc.attributes
|
108
|
+
|
109
|
+
More than likely, you want to just render the document.
|
110
|
+
|
111
|
+
.Rendering files
|
112
|
+
To render a file containing AsciiDoc markup to HTML 5:
|
113
|
+
|
114
|
+
Asciidoctor.render_file('your_file.asciidoc', :in_place => true)
|
115
|
+
|
116
|
+
The command will output to the file `your_file.html` in the same
|
117
|
+
directory. You can render the file to DocBook 4.5 by setting the
|
118
|
+
`backend` attribute to 'docbook':
|
119
|
+
|
120
|
+
Asciidoctor.render_file('your_file.asciidoc', :in_place => true,
|
121
|
+
:attributes => {'backend' => 'docbook'})
|
122
|
+
|
123
|
+
The command will output to the file `your_file.xml` in the same
|
124
|
+
directory. (If you're on Linux, you can view the file using yelp).
|
125
|
+
|
126
|
+
.Rendering strings
|
64
127
|
To render an AsciiDoc-formatted string:
|
65
128
|
|
66
|
-
|
67
|
-
|
129
|
+
puts Asciidoctor.render('*This* is it.')
|
130
|
+
|
131
|
+
When rendering a string, the header and footer are excluded by default
|
132
|
+
to make Asciidoctor consistent with other lightweight markup engines
|
133
|
+
like Markdown. If you want the header and footer, just declare it as
|
134
|
+
an option:
|
135
|
+
|
136
|
+
puts Asciidoctor.render('*This* is it.', :header_footer => true)
|
137
|
+
|
138
|
+
Now you'll get a full HTML 5 file. As before, you can also produce
|
139
|
+
DocBook 4.5:
|
68
140
|
|
141
|
+
puts Asciidoctor.render('*This* is it.', :header_footer => true,
|
142
|
+
:attributes => {'backend' => 'docbook'})
|
143
|
+
|
144
|
+
If you don't like the output you see, you can change it. Any of it!
|
145
|
+
|
146
|
+
.Custom templates
|
69
147
|
Asciidoctor allows you to override the {templates}[built-in templates]
|
70
148
|
used to render almost any individual AsciiDoc element. If you provide a
|
71
149
|
directory of {tilt}[Tilt]-compatible templates, named in such a way that
|
@@ -74,8 +152,8 @@ Asciidoctor will use the templates in this directory instead of its
|
|
74
152
|
built-in templates for any elements for which it finds a matching
|
75
153
|
template. It will fallback to its default templates for everything else.
|
76
154
|
|
77
|
-
|
78
|
-
|
155
|
+
puts Asciidoctor.render('*This* is it.', :header_footer => true,
|
156
|
+
:template_dir => 'templates')
|
79
157
|
|
80
158
|
The Document and Section templates should begin with `document.` and
|
81
159
|
`section.`, respectively. The file extension is used by Tilt to
|
@@ -90,7 +168,47 @@ template with an ERB template, put a file named
|
|
90
168
|
`block_paragraph.html.erb` in the template directory you pass to the
|
91
169
|
`Document` constructor using the `template_dir` option.
|
92
170
|
|
93
|
-
For more usage examples, see the test suite.
|
171
|
+
For more usage examples, see the (massive) test suite.
|
172
|
+
|
173
|
+
== Differences from AsciiDoc
|
174
|
+
|
175
|
+
While Asciidoctor aims to be compliant with the AsciiDoc syntax, there are some differences which are important to keep in mind. In some cases, it's to enforce a rule we believe is too lax or ambiguous in AsciiDoc. In other cases, it's a tradeoff for speed, smarter processing or a feature we just haven't yet implemented. (You'll also notice that Asciidoctor is about 20x faster than AsciiDoc).
|
176
|
+
|
177
|
+
Here are the known cases where Asciidoctor differs from AsciiDoc:
|
178
|
+
|
179
|
+
* In Asciidoctor, safe mode is on by default when using the API (safe mode level SECURE),
|
180
|
+
* Asciidoctor safe mode is even more safe than AsciiDoc's safe mode
|
181
|
+
* Asciidoctor enforces symmetric block delimiters (the length of start and end delimiters for a block must match)
|
182
|
+
* Section title underlines must be within +/- 1 of the length of the title (AsciiDoc is +/- 3)
|
183
|
+
* Asciidoctor's default HTML backend matches AsciiDoc's HTML 5 backend (whereas XHTML 1.1 is the default HTML backend in AsciiDoc)
|
184
|
+
* Asciidoctor handles inline anchors more cleanly
|
185
|
+
** AsciiDoc adds an `<a>` tag in the line and that markup gets caught in the generated id
|
186
|
+
** Asciidoctor promotes the id of the anchor as the section id
|
187
|
+
* Asciidoctor strips XML entities from the section title before generating the id (makes for cleaner section ids)
|
188
|
+
* Asciidoctor use `<tt>` instead of `<span class="monospace">` around inline literal text in the HTML backend
|
189
|
+
* Asciidoctor is much more lenient about attribute list parsing (double quotes are rarely needed)
|
190
|
+
* Asciidoctor creates xref labels using the text from the linked section title when rendering HTML to match how DocBook works
|
191
|
+
* Asciidoctor allows commas to be used in xref labels, whereas AsciiDoc cuts off the label at the location of the first comma
|
192
|
+
* Asciidoctor removes indentation for non-literal paragraphs in a list item
|
193
|
+
** In general, Asciidoctor handles whitespace much more intelligently
|
194
|
+
* In Asciidoctor, a ruler can have attributes
|
195
|
+
* Asciidoctor skips over line comments in tables, whereas AsciiDoc does not
|
196
|
+
* Asciidoctor uses its own API rather than a command line invocation to handle table cells that have AsciiDoc content
|
197
|
+
* Asciidoctor supports resolving variables from parent document in table cells with AsciiDoc content
|
198
|
+
* AsciiDoc doesn't carry over the doctype attribute passed from the commandline when rendering AsciiDoc content cells, whereas Asciidoctor does
|
199
|
+
* Asciidoctor strips the file extension from the target image when generating alt text if no alt text is provided
|
200
|
+
* Asciidoctor reifies the toc in the header of the document instead of relying on JavaScript to create it
|
201
|
+
* Asciidoctor is nice about using a section title syntax inside a delimited block by simply ignoring it (AsciiDoc issues warnings)
|
202
|
+
* Asciidoctor honors the alternate style name "discrete" for a floating title (i.e., [discrete])
|
203
|
+
* Asciidoctor supports syntax highlighting of listing or literal blocks that have the "source" style out of the box
|
204
|
+
** Asciidoctor honors the source-highlighter values `coderay` and `highlightjs`, using CodeRay or highlight.js, respectively
|
205
|
+
** Asciidoctor does not currently support Pygments for source highlighting
|
206
|
+
* Asciidoctor sets these additional intrinsic attributes
|
207
|
+
`asciidoctor`:: indicates Asciidoctor is being used; useful for conditional processing
|
208
|
+
`asciidoctor-version`:: indicates which version of Asciidoctor is in use
|
209
|
+
* Asciidoctor does not support deprecated tables (you don't want them anyway)
|
210
|
+
|
211
|
+
If there's a difference you don't see in this list, check the {issues}[issue tracker] to see if it's an outstanding feature, or file an issue to report the difference.
|
94
212
|
|
95
213
|
== Contributing
|
96
214
|
|
@@ -104,8 +222,11 @@ Here are some ways *you* can contribute:
|
|
104
222
|
* by suggesting new features
|
105
223
|
* by writing or editing documentation
|
106
224
|
* by writing specifications
|
107
|
-
* by writing code
|
108
|
-
|
225
|
+
* by writing code -- 'No patch is too small.'
|
226
|
+
** fix typos
|
227
|
+
** add comments
|
228
|
+
** clean up inconsistent whitespace
|
229
|
+
** write tests!
|
109
230
|
* by refactoring code
|
110
231
|
* by fixing {issues}[issues]
|
111
232
|
* by reviewing patches
|
@@ -138,13 +259,14 @@ An ideal bug report would include a pull request with failing specs.
|
|
138
259
|
. Add, commit, and push your changes.
|
139
260
|
. {pr}[Submit a pull request].
|
140
261
|
|
141
|
-
|
142
262
|
== Supported Ruby Versions
|
143
263
|
|
144
264
|
This library aims to support the following Ruby implementations:
|
145
265
|
|
146
266
|
* Ruby 1.8.7
|
147
267
|
* Ruby 1.9.3
|
268
|
+
* JRuby 1.7.2
|
269
|
+
* Rubinius 1.2.4
|
148
270
|
|
149
271
|
If something doesn't work on one of these interpreters, it should be
|
150
272
|
considered a bug.
|
@@ -159,7 +281,7 @@ support for that Ruby version may be dropped.
|
|
159
281
|
|
160
282
|
== Copyright
|
161
283
|
|
162
|
-
Copyright (
|
284
|
+
Copyright (C) 2012 Ryan Waldron.
|
163
285
|
See {license}[LICENSE] for details.
|
164
286
|
|
165
287
|
// vim: tw=72
|
data/Rakefile
CHANGED
@@ -49,6 +49,7 @@ require 'rake/testtask'
|
|
49
49
|
Rake::TestTask.new(:test) do |test|
|
50
50
|
test.libs << 'lib' << 'test'
|
51
51
|
test.pattern = 'test/**/*_test.rb'
|
52
|
+
test.warning = true
|
52
53
|
test.verbose = true
|
53
54
|
end
|
54
55
|
|
@@ -62,9 +63,10 @@ end
|
|
62
63
|
|
63
64
|
begin
|
64
65
|
require 'rdoc/task'
|
65
|
-
|
66
|
+
RDoc::Task.new do |rdoc|
|
66
67
|
rdoc.rdoc_dir = 'rdoc'
|
67
68
|
rdoc.title = "#{name} #{version}"
|
69
|
+
rdoc.markup = 'tomdoc' if rdoc.respond_to?(:markup)
|
68
70
|
rdoc.rdoc_files.include('README*')
|
69
71
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
70
72
|
end
|
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 = '2013-
|
16
|
+
s.version = '0.1.0'
|
17
|
+
s.date = '2013-02-04'
|
18
18
|
s.rubyforge_project = 'asciidoctor'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
## a custom homepage, consider using your GitHub URL or the like.
|
28
28
|
s.authors = ["Ryan Waldron", "Dan Allen", "Jeremy McAnally"]
|
29
29
|
s.email = 'rew@erebor.com'
|
30
|
-
s.homepage = 'http://github.com/
|
30
|
+
s.homepage = 'http://github.com/asciidoctor'
|
31
31
|
|
32
32
|
## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
|
33
33
|
## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
|
@@ -53,6 +53,7 @@ Gem::Specification.new do |s|
|
|
53
53
|
s.add_development_dependency('nokogiri')
|
54
54
|
s.add_development_dependency('pending')
|
55
55
|
s.add_development_dependency('rake')
|
56
|
+
s.add_development_dependency('rdoc', '~> 3.12')
|
56
57
|
s.add_development_dependency('tilt')
|
57
58
|
|
58
59
|
## Leave this section as-is. It will be automatically generated from the
|
@@ -66,6 +67,7 @@ Gem::Specification.new do |s|
|
|
66
67
|
Rakefile
|
67
68
|
asciidoctor.gemspec
|
68
69
|
bin/asciidoctor
|
70
|
+
bin/asciidoctor-safe
|
69
71
|
lib/asciidoctor.rb
|
70
72
|
lib/asciidoctor/abstract_block.rb
|
71
73
|
lib/asciidoctor/abstract_node.rb
|
@@ -75,6 +77,8 @@ Gem::Specification.new do |s|
|
|
75
77
|
lib/asciidoctor/backends/html5.rb
|
76
78
|
lib/asciidoctor/block.rb
|
77
79
|
lib/asciidoctor/callouts.rb
|
80
|
+
lib/asciidoctor/cli/invoker.rb
|
81
|
+
lib/asciidoctor/cli/options.rb
|
78
82
|
lib/asciidoctor/debug.rb
|
79
83
|
lib/asciidoctor/document.rb
|
80
84
|
lib/asciidoctor/errors.rb
|
@@ -87,7 +91,8 @@ Gem::Specification.new do |s|
|
|
87
91
|
lib/asciidoctor/substituters.rb
|
88
92
|
lib/asciidoctor/table.rb
|
89
93
|
lib/asciidoctor/version.rb
|
90
|
-
|
94
|
+
man/asciidoctor.1
|
95
|
+
man/asciidoctor.ad
|
91
96
|
test/attributes_test.rb
|
92
97
|
test/blocks_test.rb
|
93
98
|
test/document_test.rb
|
@@ -98,15 +103,18 @@ Gem::Specification.new do |s|
|
|
98
103
|
test/fixtures/encoding.asciidoc
|
99
104
|
test/fixtures/include-file.asciidoc
|
100
105
|
test/fixtures/list_elements.asciidoc
|
106
|
+
test/fixtures/sample.asciidoc
|
101
107
|
test/fixtures/tip.gif
|
102
|
-
test/
|
108
|
+
test/invoker_test.rb
|
103
109
|
test/lexer_test.rb
|
104
110
|
test/links_test.rb
|
105
111
|
test/lists_test.rb
|
112
|
+
test/options_test.rb
|
106
113
|
test/paragraphs_test.rb
|
107
114
|
test/preamble_test.rb
|
108
115
|
test/reader_test.rb
|
109
116
|
test/renderer_test.rb
|
117
|
+
test/sections_test.rb
|
110
118
|
test/substitutions_test.rb
|
111
119
|
test/tables_test.rb
|
112
120
|
test/test_helper.rb
|
data/bin/asciidoctor
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
$:.unshift File.dirname(__FILE__)
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
4
4
|
|
5
5
|
require 'asciidoctor'
|
6
|
-
require 'asciidoctor/cli'
|
6
|
+
require 'asciidoctor/cli/options'
|
7
|
+
require 'asciidoctor/cli/invoker'
|
7
8
|
|
8
|
-
Asciidoctor::Cli.new
|
9
|
+
invoker = Asciidoctor::Cli::Invoker.new(ARGV)
|
10
|
+
invoker.invoke!
|
11
|
+
exit invoker.code
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
4
|
+
|
5
|
+
require 'asciidoctor'
|
6
|
+
require 'asciidoctor/cli/options'
|
7
|
+
require 'asciidoctor/cli/invoker'
|
8
|
+
|
9
|
+
options = Asciidoctor::Cli::Options.parse! ARGV
|
10
|
+
options[:safe] = Asciidoctor::SafeMode::SAFE
|
11
|
+
invoker = Asciidoctor::Cli::Invoker.new(options)
|
12
|
+
invoker.invoke!
|
13
|
+
exit invoker.code
|
data/lib/asciidoctor.rb
CHANGED
@@ -57,19 +57,29 @@ module Asciidoctor
|
|
57
57
|
# the source file and disables any macro other than the include::[] macro.
|
58
58
|
SAFE = 1;
|
59
59
|
|
60
|
-
# A safe mode level that disallows the document from
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
# document.
|
65
|
-
#
|
66
|
-
|
67
|
-
|
68
|
-
|
60
|
+
# A safe mode level that disallows the document from setting attributes
|
61
|
+
# that would affect the rendering of the document, in addition to all the
|
62
|
+
# security features of SafeMode::SAFE. For instance, this level disallows
|
63
|
+
# changing the backend or the source-highlighter using an attribute defined
|
64
|
+
# in the source document. This is the most fundamental level of security
|
65
|
+
# for server-side deployments (hence the name).
|
66
|
+
SERVER = 10;
|
67
|
+
|
68
|
+
# A safe mode level that disallows the document from attempting to read
|
69
|
+
# files from the file system and including the contents of them into the
|
70
|
+
# document, in additional to all the security features of SafeMode::SERVER.
|
71
|
+
# For instance, this level disallows use of the include::[] macro and the
|
72
|
+
# embedding of binary content (data uri), stylesheets and JavaScripts
|
73
|
+
# referenced by the document.(Asciidoctor and trusted extensions may still
|
74
|
+
# be allowed to embed trusted content into the document).
|
75
|
+
#
|
76
|
+
# Since Asciidoctor is aiming for wide adoption, this level is the default
|
77
|
+
# and is recommended for server-side deployments.
|
78
|
+
SECURE = 20;
|
69
79
|
|
70
80
|
# A planned safe mode level that disallows the use of passthrough macros and
|
71
81
|
# prevents the document from setting any known attributes, in addition to all
|
72
|
-
# the security features of SafeMode::SECURE
|
82
|
+
# the security features of SafeMode::SECURE.
|
73
83
|
#
|
74
84
|
# Please note that this level is not currently implemented (and therefore not
|
75
85
|
# enforced)!
|
@@ -81,14 +91,28 @@ module Asciidoctor
|
|
81
91
|
# Can influence markup generated by render templates
|
82
92
|
DEFAULT_DOCTYPE = 'article'
|
83
93
|
|
84
|
-
#
|
94
|
+
# The backend determines the format of the rendered output, default to html5
|
85
95
|
DEFAULT_BACKEND = 'html5'
|
86
96
|
|
97
|
+
# Pointers to the preferred version for a given backend.
|
98
|
+
BACKEND_ALIASES = {
|
99
|
+
'html' => 'html5',
|
100
|
+
'docbook' => 'docbook45'
|
101
|
+
}
|
102
|
+
|
87
103
|
# Default page widths for calculating absolute widths
|
88
104
|
DEFAULT_PAGE_WIDTHS = {
|
89
105
|
'docbook' => 425
|
90
106
|
}
|
91
107
|
|
108
|
+
# Default extensions for the respective base backends
|
109
|
+
DEFAULT_EXTENSIONS = {
|
110
|
+
'html' => '.html',
|
111
|
+
'docbook' => '.xml',
|
112
|
+
'asciidoc' => '.ad',
|
113
|
+
'markdown' => '.md'
|
114
|
+
}
|
115
|
+
|
92
116
|
LIST_CONTEXTS = [:ulist, :olist, :dlist, :colist]
|
93
117
|
|
94
118
|
NESTABLE_LIST_CONTEXTS = [:ulist, :olist, :dlist]
|
@@ -109,6 +133,13 @@ module Asciidoctor
|
|
109
133
|
|
110
134
|
LINE_FEED_ENTITY = ' ' # or 

|
111
135
|
|
136
|
+
# The following pattern, which appears frequently, captures the contents between square brackets,
|
137
|
+
# ignoring escaped closing brackets (closing brackets prefixed with a backslash '\' character)
|
138
|
+
#
|
139
|
+
# Pattern:
|
140
|
+
# (?:\[((?:\\\]|[^\]])*?)\])
|
141
|
+
# Matches:
|
142
|
+
# [enclosed text here] or [enclosed [text\] here]
|
112
143
|
REGEXP = {
|
113
144
|
# [[Foo]]
|
114
145
|
:anchor => /^\[\[([^\[\]]+)\]\]\s*$/,
|
@@ -159,14 +190,15 @@ module Asciidoctor
|
|
159
190
|
|
160
191
|
# attribute reference
|
161
192
|
# {foo}
|
162
|
-
|
193
|
+
# {counter:pcount:1}
|
194
|
+
:attr_ref => /(\\?)\{(\w|\w[\w\-:]*\w)(\\?)\}/,
|
163
195
|
|
164
196
|
# The author info line the appears immediately following the document title
|
165
197
|
# John Doe <john@anonymous.com>
|
166
|
-
:author_info => /^\s*([\w\-]
|
198
|
+
:author_info => /^\s*(\w[\w\-'\.]*)(?: +(\w[\w\-'\.]*))?(?: +(\w[\w\-'\.]*))?(?: +<([^>]+)>)?\s*$/,
|
167
199
|
|
168
|
-
# [[[Foo]]]
|
169
|
-
:
|
200
|
+
# [[[Foo]]] (anywhere inline)
|
201
|
+
:biblio_macro => /\\?\[\[\[([\w:][\w:\.-]*?)\]\]\]/,
|
170
202
|
|
171
203
|
# callout reference inside literal text
|
172
204
|
# <1>
|
@@ -186,6 +218,11 @@ module Asciidoctor
|
|
186
218
|
# // (and then whatever)
|
187
219
|
:comment => %r{^//([^/].*|)$},
|
188
220
|
|
221
|
+
# one,two
|
222
|
+
# one, two
|
223
|
+
# one , two
|
224
|
+
:csv_delimiter => /[[:space:]]*,[[:space:]]*/,
|
225
|
+
|
189
226
|
# 29
|
190
227
|
:digits => /^\d+$/,
|
191
228
|
|
@@ -208,12 +245,25 @@ module Asciidoctor
|
|
208
245
|
# ====
|
209
246
|
:example => /^={4,}\s*$/,
|
210
247
|
|
248
|
+
# footnote:[text]
|
249
|
+
# footnoteref:[id,text]
|
250
|
+
# footnoteref:[id]
|
251
|
+
:footnote_macro => /\\?(footnote|footnoteref):\[((?:\\\]|[^\]])*?)\]/m,
|
252
|
+
|
211
253
|
# image::filename.png[Caption]
|
212
|
-
:image_blk => /^image::(\S+?)\[(.*?)\]
|
254
|
+
:image_blk => /^image::(\S+?)\[(.*?)\]\s*$/,
|
213
255
|
|
214
|
-
# image:filename.png[Alt]
|
256
|
+
# image:filename.png[Alt Text]
|
215
257
|
:image_macro => /\\?image:([^\[]+)(?:\[([^\]]*)\])/,
|
216
258
|
|
259
|
+
# indexterm:[Tigers,Big cats]
|
260
|
+
# (((Tigers,Big cats)))
|
261
|
+
:indexterm_macro => /\\?(?:indexterm:(?:\[((?:\\\]|[^\]])*?)\])|\(\(\((.*?)\)\)\)(?!\)))/m,
|
262
|
+
|
263
|
+
# indexterm2:[Tigers]
|
264
|
+
# ((Tigers))
|
265
|
+
:indexterm2_macro => /\\?(?:indexterm2:(?:\[((?:\\\]|[^\]])*?)\])|\(\((.*?)\)\)(?!\)))/m,
|
266
|
+
|
217
267
|
# whitespace at the beginning of the line
|
218
268
|
:leading_blanks => /^([[:blank:]]*)/,
|
219
269
|
|
@@ -228,11 +278,11 @@ module Asciidoctor
|
|
228
278
|
|
229
279
|
# inline link and some inline link macro
|
230
280
|
# FIXME revisit!
|
231
|
-
:link_inline => %r{(^|link:|\s|>|<|[\(\)\]])(\\?https?://[^\[
|
281
|
+
:link_inline => %r{(^|link:|\s|>|<|[\(\)\[\]])(\\?https?://[^\s\[<]*[^\s\.\)\[<])(?:\[((?:\\\]|[^\]])*?)\])?},
|
232
282
|
|
233
283
|
# inline link macro
|
234
284
|
# link:path[label]
|
235
|
-
:link_macro => /\\?link:([^\[
|
285
|
+
:link_macro => /\\?link:([^\s\[]+)(?:\[((?:\\\]|[^\]])*?)\])/,
|
236
286
|
|
237
287
|
# ----
|
238
288
|
:listing => /^\-{4,}\s*$/,
|
@@ -328,8 +378,8 @@ module Asciidoctor
|
|
328
378
|
#
|
329
379
|
# match[1] is the delimiter, whose length determines the level
|
330
380
|
# match[2] is the title itself
|
331
|
-
# match[3] is an
|
332
|
-
:section_title => /^(={1,5})\s+(\S.*?)\s*(?:\[\[([^\[]+)\]\]\s*)?(
|
381
|
+
# match[3] is an inline anchor, which becomes the section id
|
382
|
+
:section_title => /^(={1,5})\s+(\S.*?)\s*(?:\[\[([^\[]+)\]\]\s*)?(?:\s\1)?$/,
|
333
383
|
|
334
384
|
# does not begin with a dot and has at least one alphanumeric character
|
335
385
|
:section_name => /^((?=.*\w+.*)[^\.].*?)\s*$/,
|
@@ -458,7 +508,7 @@ module Asciidoctor
|
|
458
508
|
# (TM)
|
459
509
|
[/(^|[^\\])\(TM\)/, '\1™'],
|
460
510
|
# foo -- bar
|
461
|
-
[/ -- /, ' — '],
|
511
|
+
[/(^|\n| )-- /, ' — '],
|
462
512
|
# foo--bar
|
463
513
|
[/(\w)--(?=\w)/, '\1—'],
|
464
514
|
# ellipsis
|
@@ -467,31 +517,192 @@ module Asciidoctor
|
|
467
517
|
[/(\w)'(\w)/, '\1’\2'],
|
468
518
|
# escaped single quotes
|
469
519
|
[/(\w)\\'(\w)/, '\1\'\2'],
|
520
|
+
# right arrow ->
|
521
|
+
[/(^|[^\\])->/, '\1→'],
|
522
|
+
# right double arrow =>
|
523
|
+
[/(^|[^\\])=>/, '\1⇒'],
|
524
|
+
# left arrow <-
|
525
|
+
[/(^|[^\\])<-/, '\1←'],
|
526
|
+
# right left arrow <=
|
527
|
+
[/(^|[^\\])<=/, '\1⇐'],
|
470
528
|
# and so on...
|
471
529
|
|
472
530
|
# restore entities; TODO needs cleanup
|
473
|
-
[
|
531
|
+
[/(^|[^\\])&(#[a-z0-9]+;)/i, '\1&\2']
|
474
532
|
]
|
475
533
|
|
534
|
+
# Public: Parse the AsciiDoc source input into an Asciidoctor::Document
|
535
|
+
#
|
536
|
+
# Accepts input as an IO (or StringIO), String or String Array object. If the
|
537
|
+
# input is a File, information about the file is stored in attributes on the
|
538
|
+
# Document object.
|
539
|
+
#
|
540
|
+
# input - the AsciiDoc source as a IO, String or Array.
|
541
|
+
# options - a Hash of options to control processing (default: {})
|
542
|
+
# see Asciidoctor::Document#initialize for details
|
543
|
+
# block - a callback block for handling include::[] directives
|
544
|
+
#
|
545
|
+
# returns the Asciidoctor::Document
|
546
|
+
def self.load(input, options = {}, &block)
|
547
|
+
lines = nil
|
548
|
+
if input.is_a?(File)
|
549
|
+
options[:attributes] ||= {}
|
550
|
+
attrs = options[:attributes]
|
551
|
+
lines = input.readlines
|
552
|
+
input_mtime = input.mtime
|
553
|
+
input_path = File.expand_path(input.path)
|
554
|
+
# hold off on setting infile and indir until we get a better sense of their purpose
|
555
|
+
attrs['docfile'] = input_path
|
556
|
+
attrs['docdir'] = File.dirname(input_path)
|
557
|
+
attrs['docname'] = File.basename(input_path, File.extname(input_path))
|
558
|
+
attrs['docdate'] = input_mtime.strftime('%Y-%m-%d')
|
559
|
+
attrs['doctime'] = input_mtime.strftime('%H:%M:%S %Z')
|
560
|
+
attrs['docdatetime'] = [attrs['docdate'], attrs['doctime']] * ' '
|
561
|
+
elsif input.respond_to?(:readlines)
|
562
|
+
input.rewind rescue nil
|
563
|
+
lines = input.readlines
|
564
|
+
elsif input.is_a?(String)
|
565
|
+
lines = input.lines.entries
|
566
|
+
elsif input.is_a?(Array)
|
567
|
+
lines = input.dup
|
568
|
+
else
|
569
|
+
raise "Unsupported input type: #{input.class}"
|
570
|
+
end
|
571
|
+
|
572
|
+
Document.new(lines, options, &block)
|
573
|
+
end
|
574
|
+
|
575
|
+
# Public: Parse the contents of the AsciiDoc source file into an Asciidoctor::Document
|
576
|
+
#
|
577
|
+
# Accepts input as an IO, String or String Array object. If the
|
578
|
+
# input is a File, information about the file is stored in
|
579
|
+
# attributes on the Document.
|
580
|
+
#
|
581
|
+
# input - the String AsciiDoc source filename
|
582
|
+
# options - a Hash of options to control processing (default: {})
|
583
|
+
# see Asciidoctor::Document#initialize for details
|
584
|
+
# block - a callback block for handling include::[] directives
|
585
|
+
#
|
586
|
+
# returns the Asciidoctor::Document
|
587
|
+
def self.load_file(filename, options = {}, &block)
|
588
|
+
Asciidoctor.load(File.new(filename), options, &block)
|
589
|
+
end
|
590
|
+
|
591
|
+
# Public: Parse the AsciiDoc source input into an Asciidoctor::Document and render it
|
592
|
+
# to the specified backend format
|
593
|
+
#
|
594
|
+
# Accepts input as an IO, String or String Array object. If the
|
595
|
+
# input is a File, information about the file is stored in
|
596
|
+
# attributes on the Document.
|
597
|
+
#
|
598
|
+
# If the :in_place option is true, and the input is a File, the output is
|
599
|
+
# written to a file adjacent to the input file, having an extension that
|
600
|
+
# corresponds to the backend format. Otherwise, if the :to_file option is
|
601
|
+
# specified, the file is written to that file. If :to_file is not an absolute
|
602
|
+
# path, it is resolved relative to :to_dir, if given, otherwise the
|
603
|
+
# Document#base_dir. If the target directory does not exist, it will not be
|
604
|
+
# created unless the :mkdirs option is set to true. If the file cannot be
|
605
|
+
# written because the target directory does not exist, or because it falls
|
606
|
+
# outside of the Document#base_dir in safe mode, an IOError is raised.
|
607
|
+
#
|
608
|
+
# If the output is going to be written to a file, the header and footer are
|
609
|
+
# rendered unless specified otherwise (writing to a file implies creating a
|
610
|
+
# standalone document). Otherwise, the header and footer are not rendered by
|
611
|
+
# default and the rendered output is returned.
|
612
|
+
#
|
613
|
+
# input - the String AsciiDoc source filename
|
614
|
+
# options - a Hash of options to control processing (default: {})
|
615
|
+
# see Asciidoctor::Document#initialize for details
|
616
|
+
# block - a callback block for handling include::[] directives
|
617
|
+
#
|
618
|
+
# returns nothing if the rendered output String is written to a file,
|
619
|
+
# otherwise the rendered output String is returned
|
620
|
+
def self.render(input, options = {}, &block)
|
621
|
+
in_place = options.delete(:in_place) || false
|
622
|
+
to_file = options.delete(:to_file)
|
623
|
+
to_dir = options.delete(:to_dir)
|
624
|
+
mkdirs = options.delete(:mkdirs) || false
|
625
|
+
|
626
|
+
write_in_place = in_place && input.is_a?(File)
|
627
|
+
write_to_target = to_file || to_dir
|
628
|
+
|
629
|
+
raise ArgumentError, ':in_place with input file must not accompany :to_dir or :to_file' if write_in_place && write_to_target
|
630
|
+
|
631
|
+
if !options.has_key?(:header_footer) && (write_in_place || write_to_target)
|
632
|
+
options[:header_footer] = true
|
633
|
+
end
|
634
|
+
|
635
|
+
doc = Asciidoctor.load(input, options, &block)
|
636
|
+
|
637
|
+
if write_in_place
|
638
|
+
to_file = File.join(File.dirname(input.path), "#{doc.attributes['docname']}#{doc.attributes['outfilesuffix']}")
|
639
|
+
elsif write_to_target
|
640
|
+
if to_dir
|
641
|
+
to_dir = doc.normalize_asset_path(to_dir, 'to_dir', false)
|
642
|
+
if to_file
|
643
|
+
# normalize again, to_file could have dirty bits
|
644
|
+
to_file = doc.normalize_asset_path(File.expand_path(to_file, to_dir), 'to_file', false)
|
645
|
+
# reestablish to_dir as the final target directory (in the case to_file had directory segments)
|
646
|
+
to_dir = File.dirname(to_file)
|
647
|
+
else
|
648
|
+
to_file = File.join(to_dir, "#{doc.attributes['docname']}#{doc.attributes['outfilesuffix']}")
|
649
|
+
end
|
650
|
+
elsif to_file
|
651
|
+
to_file = doc.normalize_asset_path(to_file, 'to_file', false)
|
652
|
+
to_dir = File.dirname(to_file)
|
653
|
+
end
|
654
|
+
|
655
|
+
if !File.directory? to_dir
|
656
|
+
if mkdirs
|
657
|
+
require_library 'fileutils'
|
658
|
+
FileUtils.mkdir_p to_dir
|
659
|
+
else
|
660
|
+
raise IOError, "target directory does not exist: #{to_dir}"
|
661
|
+
end
|
662
|
+
end
|
663
|
+
end
|
664
|
+
|
665
|
+
if to_file
|
666
|
+
File.open(to_file, 'w') {|file| file.write doc.render }
|
667
|
+
nil
|
668
|
+
else
|
669
|
+
doc.render
|
670
|
+
end
|
671
|
+
end
|
672
|
+
|
673
|
+
# Public: Parse the contents of the AsciiDoc source file into an Asciidoctor::Document
|
674
|
+
# and render it to the specified backend format
|
675
|
+
#
|
676
|
+
# input - the String AsciiDoc source filename
|
677
|
+
# options - a Hash of options to control processing (default: {})
|
678
|
+
# see Asciidoctor::Document#initialize for details
|
679
|
+
# block - a callback block for handling include::[] directives
|
680
|
+
#
|
681
|
+
# returns nothing if the rendered output String is written to a file,
|
682
|
+
# otherwise the rendered output String is returned
|
683
|
+
def self.render_file(filename, options = {}, &block)
|
684
|
+
Asciidoctor.render(File.new(filename), options, &block)
|
685
|
+
end
|
686
|
+
|
476
687
|
# Internal: Prior to invoking Kernel#require, issues a warning urging a
|
477
688
|
# manual require if running in a threaded environment.
|
478
689
|
#
|
479
690
|
# name - the String name of the library to require.
|
480
691
|
#
|
481
|
-
# returns
|
692
|
+
# returns false if the library is detected on the load path or the return
|
693
|
+
# value of delegating to Kernel#require
|
482
694
|
def self.require_library(name)
|
483
695
|
if Thread.list.size > 1
|
484
696
|
main_script = "#{name}.rb"
|
485
697
|
main_script_path_segment = "/#{name}.rb"
|
486
698
|
if !$LOADED_FEATURES.detect {|p| p == main_script || p.end_with?(main_script_path_segment) }.nil?
|
487
|
-
return
|
699
|
+
return false
|
488
700
|
else
|
489
701
|
warn "WARN: asciidoctor is autoloading '#{name}' in threaded environment. " +
|
490
702
|
"The use of an explicit require '#{name}' statement is recommended."
|
491
703
|
end
|
492
704
|
end
|
493
705
|
require name
|
494
|
-
nil
|
495
706
|
end
|
496
707
|
|
497
708
|
# modules
|