asciidoctor 1.5.2 → 1.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of asciidoctor might be problematic. Click here for more details.

Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +107 -1
  3. data/LICENSE.adoc +1 -1
  4. data/README.adoc +155 -230
  5. data/Rakefile +2 -1
  6. data/bin/asciidoctor +5 -1
  7. data/data/stylesheets/asciidoctor-default.css +37 -29
  8. data/data/stylesheets/coderay-asciidoctor.css +3 -3
  9. data/features/text_formatting.feature +2 -0
  10. data/lib/asciidoctor.rb +46 -21
  11. data/lib/asciidoctor/abstract_block.rb +14 -8
  12. data/lib/asciidoctor/abstract_node.rb +77 -24
  13. data/lib/asciidoctor/attribute_list.rb +1 -1
  14. data/lib/asciidoctor/block.rb +2 -3
  15. data/lib/asciidoctor/cli/options.rb +14 -15
  16. data/lib/asciidoctor/converter/docbook45.rb +8 -8
  17. data/lib/asciidoctor/converter/docbook5.rb +25 -17
  18. data/lib/asciidoctor/converter/factory.rb +6 -1
  19. data/lib/asciidoctor/converter/html5.rb +159 -117
  20. data/lib/asciidoctor/converter/manpage.rb +671 -0
  21. data/lib/asciidoctor/converter/template.rb +24 -17
  22. data/lib/asciidoctor/document.rb +89 -47
  23. data/lib/asciidoctor/extensions.rb +22 -21
  24. data/lib/asciidoctor/helpers.rb +73 -16
  25. data/lib/asciidoctor/list.rb +26 -5
  26. data/lib/asciidoctor/parser.rb +179 -122
  27. data/lib/asciidoctor/path_resolver.rb +6 -10
  28. data/lib/asciidoctor/reader.rb +37 -34
  29. data/lib/asciidoctor/stylesheets.rb +16 -10
  30. data/lib/asciidoctor/substitutors.rb +98 -21
  31. data/lib/asciidoctor/table.rb +21 -17
  32. data/lib/asciidoctor/timings.rb +3 -3
  33. data/lib/asciidoctor/version.rb +1 -1
  34. data/man/asciidoctor.1 +155 -89
  35. data/man/asciidoctor.adoc +19 -11
  36. data/test/attributes_test.rb +86 -0
  37. data/test/blocks_test.rb +203 -15
  38. data/test/converter_test.rb +15 -2
  39. data/test/document_test.rb +290 -36
  40. data/test/extensions_test.rb +22 -3
  41. data/test/fixtures/circle.svg +8 -0
  42. data/test/fixtures/subs-docinfo.html +2 -0
  43. data/test/fixtures/subs.adoc +7 -0
  44. data/test/invoker_test.rb +25 -0
  45. data/test/links_test.rb +17 -0
  46. data/test/lists_test.rb +173 -0
  47. data/test/options_test.rb +2 -2
  48. data/test/paragraphs_test.rb +2 -2
  49. data/test/parser_test.rb +56 -13
  50. data/test/reader_test.rb +35 -3
  51. data/test/sections_test.rb +59 -0
  52. data/test/substitutions_test.rb +53 -14
  53. data/test/tables_test.rb +158 -2
  54. data/test/test_helper.rb +7 -2
  55. metadata +22 -11
  56. data/benchmark/benchmark.rb +0 -129
  57. data/benchmark/sample-data/mdbasics.adoc +0 -334
  58. data/lib/asciidoctor/opal_ext.rb +0 -26
  59. data/lib/asciidoctor/opal_ext/comparable.rb +0 -38
  60. data/lib/asciidoctor/opal_ext/dir.rb +0 -13
  61. data/lib/asciidoctor/opal_ext/error.rb +0 -2
  62. data/lib/asciidoctor/opal_ext/file.rb +0 -145
data/Rakefile CHANGED
@@ -127,9 +127,10 @@ begin
127
127
  require 'bundler/gem_tasks'
128
128
 
129
129
  # Enhance the release task to create an explicit commit for the release
130
- Rake::Task[:release].enhance [:commit_release]
130
+ #Rake::Task[:release].enhance [:commit_release]
131
131
 
132
132
  # NOTE you don't need to push after updating version and committing locally
133
+ # WARNING no longer works; it's now necessary to get master in a state ready for tagging
133
134
  task :commit_release do
134
135
  Bundler::GemHelper.new.send(:guard_clean)
135
136
  sh "git commit --allow-empty -a -m 'Release #{Asciidoctor::VERSION}'"
@@ -2,7 +2,11 @@
2
2
 
3
3
  require 'rubygems' if RUBY_VERSION < '1.9'
4
4
 
5
- require File.join File.dirname(__FILE__), '../lib/asciidoctor'
5
+ if File.exist?(asciidoctor_lib_path = File.join(File.dirname(__FILE__), '../lib/asciidoctor'))
6
+ require asciidoctor_lib_path
7
+ else
8
+ require 'asciidoctor'
9
+ end
6
10
  require 'asciidoctor/cli'
7
11
 
8
12
  invoker = Asciidoctor::Cli::Invoker.new ARGV
@@ -1,6 +1,6 @@
1
1
  /* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
2
- /* Remove the comments around the @import statement below when using this as a custom stylesheet */
3
- /*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400";*/
2
+ /* Remove comment around @import statement below when using as a custom stylesheet */
3
+ /*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
4
4
  article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
5
5
  audio,canvas,video{display:inline-block}
6
6
  audio:not([controls]){display:none;height:0}
@@ -47,7 +47,6 @@ a:hover{cursor:pointer}
47
47
  img,object,embed{max-width:100%;height:auto}
48
48
  object,embed{height:100%}
49
49
  img{-ms-interpolation-mode:bicubic}
50
- #map_canvas img,#map_canvas embed,#map_canvas object,.map_canvas img,.map_canvas embed,.map_canvas object{max-width:none!important}
51
50
  .left{float:left!important}
52
51
  .right{float:right!important}
53
52
  .text-left{text-align:left!important}
@@ -55,10 +54,12 @@ img{-ms-interpolation-mode:bicubic}
55
54
  .text-center{text-align:center!important}
56
55
  .text-justify{text-align:justify!important}
57
56
  .hide{display:none}
58
- .antialiased,body{-webkit-font-smoothing:antialiased}
59
- img{display:inline-block;vertical-align:middle}
57
+ body{-webkit-font-smoothing:antialiased}
58
+ img,object,svg{display:inline-block;vertical-align:middle}
60
59
  textarea{height:auto;min-height:50px}
61
60
  select{width:100%}
61
+ .center{margin-left:auto;margin-right:auto}
62
+ .spread{width:100%}
62
63
  p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
63
64
  .subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
64
65
  div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
@@ -101,12 +102,14 @@ blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
101
102
  h1{font-size:2.75em}
102
103
  h2{font-size:2.3125em}
103
104
  h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
104
- h4{font-size:1.4375em}}table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
105
+ h4{font-size:1.4375em}}
106
+ table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
105
107
  table thead,table tfoot{background:#f7f8f7;font-weight:bold}
106
108
  table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
107
109
  table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
108
110
  table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
109
111
  table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
112
+ body{tab-size:4}
110
113
  h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
111
114
  h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
112
115
  .clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
@@ -114,7 +117,7 @@ h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title str
114
117
  *:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
115
118
  pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
116
119
  .keyseq{color:rgba(51,51,51,.8)}
117
- kbd{display:inline-block;color:rgba(0,0,0,.8);font-size:.75em;line-height:1.4;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:-.15em .15em 0 .15em;padding:.2em .6em .2em .5em;vertical-align:middle;white-space:nowrap}
120
+ kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
118
121
  .keyseq kbd:first-child{margin-left:0}
119
122
  .keyseq kbd:last-child{margin-right:0}
120
123
  .menuseq,.menu{color:rgba(0,0,0,.8)}
@@ -145,29 +148,33 @@ p a>code:hover{color:rgba(0,0,0,.9)}
145
148
  #toc ul.sectlevel0>li>a{font-style:italic}
146
149
  #toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
147
150
  #toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
151
+ #toc li{line-height:1.3334;margin-top:.3334em}
148
152
  #toc a{text-decoration:none}
149
153
  #toc a:active{text-decoration:underline}
150
154
  #toctitle{color:#7a2518;font-size:1.2em}
151
155
  @media only screen and (min-width:768px){#toctitle{font-size:1.375em}
152
156
  body.toc2{padding-left:15em;padding-right:0}
153
157
  #toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
154
- #toc.toc2 #toctitle{margin-top:0;font-size:1.2em}
158
+ #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
155
159
  #toc.toc2>ul{font-size:.9em;margin-bottom:0}
156
160
  #toc.toc2 ul ul{margin-left:0;padding-left:1em}
157
161
  #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
158
162
  body.toc2.toc-right{padding-left:0;padding-right:15em}
159
- body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
163
+ body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
164
+ @media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
160
165
  #toc.toc2{width:20em}
161
166
  #toc.toc2 #toctitle{font-size:1.375em}
162
167
  #toc.toc2>ul{font-size:.95em}
163
168
  #toc.toc2 ul ul{padding-left:1.25em}
164
- body.toc2.toc-right{padding-left:0;padding-right:20em}}#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
169
+ body.toc2.toc-right{padding-left:0;padding-right:20em}}
170
+ #content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
165
171
  #content #toc>:first-child{margin-top:0}
166
172
  #content #toc>:last-child{margin-bottom:0}
167
173
  #footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
168
174
  #footer-text{color:rgba(255,255,255,.8);line-height:1.44}
169
175
  .sect1{padding-bottom:.625em}
170
- @media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}.sect1+.sect1{border-top:1px solid #efefed}
176
+ @media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}
177
+ .sect1+.sect1{border-top:1px solid #efefed}
171
178
  #content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
172
179
  #content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
173
180
  #content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
@@ -196,7 +203,9 @@ table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inh
196
203
  .sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
197
204
  .literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
198
205
  .literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
199
- @media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
206
+ @media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
207
+ @media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
208
+ .literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
200
209
  .listingblock pre.highlightjs{padding:0}
201
210
  .listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
202
211
  .listingblock pre.prettyprint{border-width:0}
@@ -206,7 +215,7 @@ table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inh
206
215
  .listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
207
216
  .listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
208
217
  table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
209
- table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0}
218
+ table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
210
219
  table.pyhltable td.code{padding-left:.75em;padding-right:0}
211
220
  pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
212
221
  pre.pygments .lineno{display:inline-block;margin-right:.25em}
@@ -227,13 +236,12 @@ table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
227
236
  .verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
228
237
  .quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
229
238
  .quoteblock .attribution br,.verseblock .attribution br{display:none}
230
- .quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.05em;color:rgba(0,0,0,.6)}
239
+ .quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
231
240
  .quoteblock.abstract{margin:0 0 1.25em 0;display:block}
232
241
  .quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
233
242
  .quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
234
243
  table.tableblock{max-width:100%;border-collapse:separate}
235
244
  table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
236
- table.spread{width:100%}
237
245
  table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
238
246
  table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
239
247
  table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
@@ -279,8 +287,8 @@ ol.upperroman{list-style-type:upper-roman}
279
287
  ol.lowergreek{list-style-type:lower-greek}
280
288
  .hdlist>table,.colist>table{border:0;background:none}
281
289
  .hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
282
- td.hdlist1{padding-right:.75em;font-weight:bold}
283
- td.hdlist1,td.hdlist2{vertical-align:top}
290
+ td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
291
+ td.hdlist1{font-weight:bold;padding-bottom:1.25em}
284
292
  .literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
285
293
  .colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
286
294
  .colist>table tr>td:last-of-type{padding:.25em 0}
@@ -293,13 +301,14 @@ td.hdlist1,td.hdlist2{vertical-align:top}
293
301
  .image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
294
302
  .image.left{margin-right:.625em}
295
303
  .image.right{margin-left:.625em}
296
- a.image{text-decoration:none}
297
- span.footnote,span.footnoteref{vertical-align:super;font-size:.875em}
298
- span.footnote a,span.footnoteref a{text-decoration:none}
299
- span.footnote a:active,span.footnoteref a:active{text-decoration:underline}
304
+ a.image{text-decoration:none;display:inline-block}
305
+ a.image object{pointer-events:none}
306
+ sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
307
+ sup.footnote a,sup.footnoteref a{text-decoration:none}
308
+ sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
300
309
  #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
301
310
  #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
302
- #footnotes .footnote{padding:0 .375em;line-height:1.3;font-size:.875em;margin-left:1.2em;text-indent:-1.2em;margin-bottom:.2em}
311
+ #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}
303
312
  #footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
304
313
  #footnotes .footnote:last-of-type{margin-bottom:0}
305
314
  #content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
@@ -357,11 +366,10 @@ span.icon>.fa{cursor:default}
357
366
  pre .conum[data-value]{position:relative;top:-.125em}
358
367
  b.conum *{color:inherit!important}
359
368
  .conum:not([data-value]):empty{display:none}
360
- h1,h2{letter-spacing:-.01em}
361
- dt,th.tableblock,td.content{text-rendering:optimizeLegibility}
362
- p,td.content{letter-spacing:-.01em}
363
- p strong,td.content strong{letter-spacing:-.005em}
364
- p,blockquote,dt,td.content{font-size:1.0625rem}
369
+ dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
370
+ h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
371
+ p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
372
+ p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
365
373
  p{margin-bottom:1.25rem}
366
374
  .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
367
375
  .exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
@@ -372,9 +380,9 @@ a{color:inherit!important;text-decoration:underline!important}
372
380
  a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
373
381
  a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
374
382
  abbr[title]:after{content:" (" attr(title) ")"}
375
- pre,blockquote,tr,img{page-break-inside:avoid}
383
+ pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
376
384
  thead{display:table-header-group}
377
- img{max-width:100%!important}
385
+ svg{max-width:100%}
378
386
  p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
379
387
  h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
380
388
  #toc,.sidebarblock,.exampleblock>.content{background:none!important}
@@ -2,9 +2,9 @@
2
2
  /*pre.CodeRay {background-color:#f7f7f8;}*/
3
3
  .CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em}
4
4
  .CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)}
5
- .CodeRay .line-numbers strong{font-weight: normal}
5
+ .CodeRay .line-numbers strong{color:rgba(0,0,0,.4)}
6
6
  table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none}
7
- table.CodeRay td{vertical-align: top}
7
+ table.CodeRay td{vertical-align: top;line-height:1.45}
8
8
  table.CodeRay td.line-numbers{text-align:right}
9
9
  table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)}
10
10
  table.CodeRay td.code{padding:0 0 0 .5em}
@@ -39,7 +39,7 @@ table.CodeRay td.code>pre{padding:0}
39
39
  .CodeRay .hex{color:#058}
40
40
  .CodeRay .integer,.CodeRay .float{color:#099}
41
41
  .CodeRay .include{color:#555}
42
- .CodeRay .inline{color:#00}
42
+ .CodeRay .inline{color:#000}
43
43
  .CodeRay .inline .inline{background:#ccc}
44
44
  .CodeRay .inline .inline .inline{background:#bbb}
45
45
  .CodeRay .inline .inline-delimiter{color:#d14}
@@ -44,6 +44,8 @@ Feature: Text Formatting
44
44
  Scenario: Convert text that has ex-inline monospaced formatting
45
45
  Given the AsciiDoc source
46
46
  """
47
+ :encoding: UTF-8
48
+
47
49
  The document is assumed to be encoded as [x-]+{encoding}+.
48
50
  """
49
51
  When it is converted to html
@@ -9,8 +9,7 @@ require 'set'
9
9
 
10
10
  # NOTE RUBY_ENGINE == 'opal' conditional blocks are filtered by the Opal preprocessor
11
11
  if RUBY_ENGINE == 'opal'
12
- require 'encoding' # needed for String.bytes method
13
- require 'strscan'
12
+ # NOTE asciidoctor/opal_ext is supplied by the Asciidoctor.js build
14
13
  require 'asciidoctor/opal_ext'
15
14
  else
16
15
  autoload :Base64, 'base64'
@@ -219,9 +218,6 @@ module Asciidoctor
219
218
  # String for matching tab character
220
219
  TAB = "\t"
221
220
 
222
- # Regexp for replacing tab character
223
- TAB_PATTERN = /\t/
224
-
225
221
  # The default document type
226
222
  # Can influence markup generated by the converters
227
223
  DEFAULT_DOCTYPE = 'article'
@@ -417,7 +413,10 @@ module Asciidoctor
417
413
  #
418
414
  # Examples
419
415
  #
416
+ # v1.0
417
+ # 2013-01-01
420
418
  # v1.0, 2013-01-01: Ring in the new year release
419
+ # 1.0, Jan 01, 2013
421
420
  #
422
421
  RevisionInfoLineRx = /^(?:\D*(.*?),)?(?:\s*(?!:)(.*?))(?:\s*(?!^):\s*(.*))?$/
423
422
 
@@ -649,7 +648,7 @@ module Asciidoctor
649
648
  ## Lists
650
649
 
651
650
  # Detects the start of any list item.
652
- AnyListRx = /^(?:<?\d+>#{CG_BLANK}+#{CG_GRAPH}|#{CG_BLANK}*(?:-|(?:\*|\.){1,5}|\d+\.|[a-zA-Z]\.|[IVXivx]+\))#{CG_BLANK}+#{CG_GRAPH}|#{CG_BLANK}*.*?(?::{2,4}|;;)(?:#{CG_BLANK}+#{CG_GRAPH}|$))/
651
+ AnyListRx = /^(?:<?\d+>#{CG_BLANK}+#{CG_GRAPH}|#{CG_BLANK}*(?:-|(?:\*|\.|\u2022){1,5}|\d+\.|[a-zA-Z]\.|[IVXivx]+\))#{CG_BLANK}+#{CG_GRAPH}|#{CG_BLANK}*.*?(?::{2,4}|;;)(?:#{CG_BLANK}+#{CG_GRAPH}|$))/
653
652
 
654
653
  # Matches an unordered list item (one level for hyphens, up to 5 levels for asterisks).
655
654
  #
@@ -659,7 +658,7 @@ module Asciidoctor
659
658
  # - Foo
660
659
  #
661
660
  # NOTE we know trailing (.*) will match at least one character because we strip trailing spaces
662
- UnorderedListRx = /^#{CG_BLANK}*(-|\*{1,5})#{CG_BLANK}+(.*)$/
661
+ UnorderedListRx = /^#{CG_BLANK}*(-|\*{1,5}|\u2022{1,5})#{CG_BLANK}+(.*)$/
663
662
 
664
663
  # Matches an ordered list item (explicit numbering or up to 5 consecutive dots).
665
664
  #
@@ -741,7 +740,7 @@ module Asciidoctor
741
740
  #
742
741
  # NOTE extract regexps are applied line-by-line, so we can use $ as end-of-line char
743
742
  CalloutExtractRx = /(?:(?:\/\/|#|--|;;) ?)?(\\)?<!?(--|)(\d+)\2>(?=(?: ?\\?<!?\2\d+\2>)*$)/
744
- CalloutExtractRxt = "(\\\\)?<()(\\d+)>(?=(?: ?\\\\?<\\d+>)*$)"
743
+ CalloutExtractRxt = '(\\\\)?<()(\\d+)>(?=(?: ?\\\\?<\\d+>)*$)'
745
744
  # NOTE special characters have not been replaced when scanning
746
745
  CalloutQuickScanRx = /\\?<!?(--|)(\d+)\1>(?=(?: ?\\?<!?\1\d+\1>)*#{CC_EOL})/
747
746
  # NOTE special characters have already been replaced when converting to an SGML format
@@ -963,7 +962,7 @@ module Asciidoctor
963
962
  # xref:id[reftext]
964
963
  #
965
964
  # NOTE special characters have already been escaped, hence the entity references
966
- XrefInlineMacroRx = /\\?(?:&lt;&lt;([#{CC_WORD}":]#{CC_ALL}*?)&gt;&gt;|xref:([#{CC_WORD}":]#{CC_ALL}*?)\[(#{CC_ALL}*?)\])/m
965
+ XrefInlineMacroRx = /\\?(?:&lt;&lt;([#{CC_WORD}":.\/]#{CC_ALL}*?)&gt;&gt;|xref:([#{CC_WORD}":.\/]#{CC_ALL}*?)\[(#{CC_ALL}*?)\])/m
967
966
 
968
967
  ## Layout
969
968
 
@@ -1325,9 +1324,9 @@ module Asciidoctor
1325
1324
  # hold off on setting infile and indir until we get a better sense of their purpose
1326
1325
  attributes['docfile'] = input_path
1327
1326
  attributes['docdir'] = ::File.dirname input_path
1328
- attributes['docname'] = ::File.basename input_path, (::File.extname input_path)
1329
- attributes['docdate'] = docdate = input_mtime.strftime('%Y-%m-%d')
1330
- attributes['doctime'] = doctime = input_mtime.strftime('%H:%M:%S %Z')
1327
+ attributes['docname'] = Helpers.basename input_path, true
1328
+ docdate = (attributes['docdate'] ||= input_mtime.strftime('%Y-%m-%d'))
1329
+ doctime = (attributes['doctime'] ||= input_mtime.strftime('%H:%M:%S %Z'))
1331
1330
  attributes['docdatetime'] = %(#{docdate} #{doctime})
1332
1331
  elsif input.respond_to? :readlines
1333
1332
  # NOTE tty, pipes & sockets can't be rewound, but can't be sniffed easily either
@@ -1358,8 +1357,23 @@ module Asciidoctor
1358
1357
 
1359
1358
  timings.record :parse if timings
1360
1359
  doc
1361
- rescue => e
1362
- raise e.class, %(asciidoctor: FAILED: #{attributes.fetch 'docfile', '<stdin>'}: Failed to parse source, #{e.message})
1360
+ rescue => ex
1361
+ begin
1362
+ context = %(asciidoctor: FAILED: #{attributes['docfile'] || '<stdin>'}: Failed to load AsciiDoc document)
1363
+ if ex.respond_to? :exception
1364
+ # The original message must be explicitely preserved when wrapping a Ruby exception
1365
+ wrapped_ex = ex.exception %(#{context} - #{ex.message})
1366
+ # JRuby automatically sets backtrace, but not MRI
1367
+ wrapped_ex.set_backtrace ex.backtrace
1368
+ else
1369
+ # Likely a Java exception class
1370
+ wrapped_ex = ex.class.new context, ex
1371
+ wrapped_ex.stack_trace = ex.stack_trace
1372
+ end
1373
+ rescue
1374
+ wrapped_ex = ex
1375
+ end
1376
+ raise wrapped_ex
1363
1377
  end
1364
1378
 
1365
1379
  # Public: Parse the contents of the AsciiDoc source file into an Asciidoctor::Document
@@ -1409,6 +1423,7 @@ module Asciidoctor
1409
1423
  # file, otherwise the converted String
1410
1424
  def convert input, options = {}
1411
1425
  options = options.dup
1426
+ options.delete(:parse)
1412
1427
  to_file = options.delete(:to_file)
1413
1428
  to_dir = options.delete(:to_dir)
1414
1429
  mkdirs = options.delete(:mkdirs) || false
@@ -1458,7 +1473,7 @@ module Asciidoctor
1458
1473
  doc = self.load input, options
1459
1474
 
1460
1475
  if write_to_same_dir
1461
- outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.attributes['outfilesuffix']})
1476
+ outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.outfilesuffix})
1462
1477
  if outfile == input_path
1463
1478
  raise ::IOError, %(input file and output file cannot be the same: #{outfile})
1464
1479
  end
@@ -1473,7 +1488,7 @@ module Asciidoctor
1473
1488
  # reestablish outdir as the final target directory (in the case to_file had directory segments)
1474
1489
  outdir = ::File.dirname outfile
1475
1490
  else
1476
- outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.attributes['outfilesuffix']})
1491
+ outfile = ::File.join outdir, %(#{doc.attributes['docname']}#{doc.outfilesuffix})
1477
1492
  end
1478
1493
  elsif to_file
1479
1494
  outfile = doc.normalize_system_path(to_file, working_dir, jail, :target_name => 'to_dir', :recover => false)
@@ -1505,14 +1520,23 @@ module Asciidoctor
1505
1520
  timings.record :write if timings
1506
1521
 
1507
1522
  # NOTE document cannot control this behavior if safe >= SafeMode::SERVER
1508
- if !stream_output && doc.safe < SafeMode::SECURE && (doc.attr? 'basebackend-html') &&
1509
- (doc.attr? 'linkcss') && (doc.attr? 'copycss')
1510
- copy_asciidoctor_stylesheet = DEFAULT_STYLESHEET_KEYS.include?(stylesheet = (doc.attr 'stylesheet'))
1511
- copy_user_stylesheet = !copy_asciidoctor_stylesheet && !stylesheet.nil_or_empty?
1523
+ # NOTE skip if stylesdir is a URI
1524
+ if !stream_output && doc.safe < SafeMode::SECURE && (doc.attr? 'linkcss') &&
1525
+ (doc.attr? 'copycss') && (doc.attr? 'basebackend-html') &&
1526
+ !((stylesdir = (doc.attr 'stylesdir')) && (Helpers.uriish? stylesdir))
1527
+ copy_asciidoctor_stylesheet = false
1528
+ copy_user_stylesheet = false
1529
+ if (stylesheet = (doc.attr 'stylesheet'))
1530
+ if DEFAULT_STYLESHEET_KEYS.include? stylesheet
1531
+ copy_asciidoctor_stylesheet = true
1532
+ elsif !(Helpers.uriish? stylesheet)
1533
+ copy_user_stylesheet = true
1534
+ end
1535
+ end
1512
1536
  copy_coderay_stylesheet = (doc.attr? 'source-highlighter', 'coderay') && (doc.attr 'coderay-css', 'class') == 'class'
1513
1537
  copy_pygments_stylesheet = (doc.attr? 'source-highlighter', 'pygments') && (doc.attr 'pygments-css', 'class') == 'class'
1514
1538
  if copy_asciidoctor_stylesheet || copy_user_stylesheet || copy_coderay_stylesheet || copy_pygments_stylesheet
1515
- stylesoutdir = doc.normalize_system_path(doc.attr('stylesdir'), outdir, doc.safe >= SafeMode::SAFE ? outdir : nil)
1539
+ stylesoutdir = doc.normalize_system_path(stylesdir, outdir, doc.safe >= SafeMode::SAFE ? outdir : nil)
1516
1540
  Helpers.mkdir_p stylesoutdir if mkdirs
1517
1541
 
1518
1542
  if copy_asciidoctor_stylesheet
@@ -1522,6 +1546,7 @@ module Asciidoctor
1522
1546
  if (stylesheet_src = (doc.attr 'copycss')).empty?
1523
1547
  stylesheet_src = doc.normalize_system_path stylesheet
1524
1548
  else
1549
+ # NOTE in this case, copycss is a source location (but cannot be a URI)
1525
1550
  stylesheet_src = doc.normalize_system_path stylesheet_src
1526
1551
  end
1527
1552
  stylesheet_dst = doc.normalize_system_path stylesheet, stylesoutdir, (doc.safe >= SafeMode::SAFE ? outdir : nil)
@@ -248,7 +248,7 @@ class AbstractBlock < AbstractNode
248
248
  # doc.find_by context: :listing, style: 'source'
249
249
  # #=> Asciidoctor::Block@13136720 { context: :listing, content_model: :verbatim, style: "source", lines: 1 }
250
250
  #
251
- # Returns An Array of block nodes that match the given selector or nil if no matches are found
251
+ # Returns An Array of block nodes that match the given selector or an empty Array if no matches are found
252
252
  #--
253
253
  # TODO support jQuery-style selector (e.g., image.thumb)
254
254
  def find_by selector = {}, &block
@@ -256,18 +256,24 @@ class AbstractBlock < AbstractNode
256
256
 
257
257
  if ((any_context = !(context_selector = selector[:context])) || context_selector == @context) &&
258
258
  (!(style_selector = selector[:style]) || style_selector == @style) &&
259
- (!(role_selector = selector[:role]) || has_role?(role_selector)) &&
259
+ (!(role_selector = selector[:role]) || (has_role? role_selector)) &&
260
260
  (!(id_selector = selector[:id]) || id_selector == @id)
261
261
  if id_selector
262
- return [(block_given? && yield(self) ? self : self)]
262
+ if block_given?
263
+ return (yield self) ? [self] : result
264
+ else
265
+ return [self]
266
+ end
267
+ elsif block_given?
268
+ result << self if (yield self)
263
269
  else
264
- result << (block_given? && yield(self) ? self : self)
270
+ result << self
265
271
  end
266
272
  end
267
273
 
268
274
  # process document header as a section if present
269
275
  if @context == :document && (any_context || context_selector == :section) && header?
270
- result.concat(@header.find_by(selector, &block) || [])
276
+ result.concat(@header.find_by selector, &block)
271
277
  end
272
278
 
273
279
  # yuck, dlist is a special case
@@ -275,17 +281,17 @@ class AbstractBlock < AbstractNode
275
281
  if @context == :dlist
276
282
  if any_context || context_selector != :section # optimization
277
283
  @blocks.flatten.each do |li|
278
- result.concat(li.find_by(selector, &block) || [])
284
+ result.concat(li.find_by selector, &block)
279
285
  end
280
286
  end
281
287
  elsif
282
288
  @blocks.each do |b|
283
289
  next if (context_selector == :section && b.context != :section) # optimization
284
- result.concat(b.find_by(selector, &block) || [])
290
+ result.concat(b.find_by selector, &block)
285
291
  end
286
292
  end
287
293
  end
288
- result.empty? ? nil : result
294
+ result
289
295
  end
290
296
  alias :query :find_by
291
297