asciidoctor 0.1.4 → 1.5.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.

Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +209 -25
  3. data/{LICENSE → LICENSE.adoc} +4 -3
  4. data/README.adoc +392 -395
  5. data/Rakefile +94 -137
  6. data/benchmark/benchmark.rb +127 -0
  7. data/benchmark/sample-data/mdbasics.adoc +334 -0
  8. data/bin/asciidoctor +5 -8
  9. data/bin/asciidoctor-safe +4 -8
  10. data/compat/asciidoc.conf +78 -11
  11. data/compat/font-awesome-3-compat.css +397 -0
  12. data/data/stylesheets/asciidoctor-default.css +399 -0
  13. data/data/stylesheets/coderay-asciidoctor.css +89 -0
  14. data/features/open_block.feature +92 -0
  15. data/features/pass_block.feature +66 -0
  16. data/features/step_definitions.rb +42 -0
  17. data/features/text_formatting.feature +55 -0
  18. data/features/xref.feature +116 -0
  19. data/lib/asciidoctor.rb +1155 -605
  20. data/lib/asciidoctor/abstract_block.rb +157 -71
  21. data/lib/asciidoctor/abstract_node.rb +150 -93
  22. data/lib/asciidoctor/attribute_list.rb +85 -90
  23. data/lib/asciidoctor/block.rb +51 -24
  24. data/lib/asciidoctor/callouts.rb +4 -7
  25. data/lib/asciidoctor/cli.rb +3 -0
  26. data/lib/asciidoctor/cli/invoker.rb +86 -76
  27. data/lib/asciidoctor/cli/options.rb +111 -61
  28. data/lib/asciidoctor/converter.rb +232 -0
  29. data/lib/asciidoctor/converter/base.rb +58 -0
  30. data/lib/asciidoctor/converter/composite.rb +66 -0
  31. data/lib/asciidoctor/converter/docbook45.rb +94 -0
  32. data/lib/asciidoctor/converter/docbook5.rb +684 -0
  33. data/lib/asciidoctor/converter/factory.rb +225 -0
  34. data/lib/asciidoctor/converter/html5.rb +1081 -0
  35. data/lib/asciidoctor/converter/template.rb +296 -0
  36. data/lib/asciidoctor/core_ext.rb +7 -0
  37. data/lib/asciidoctor/core_ext/object/nil_or_empty.rb +23 -0
  38. data/lib/asciidoctor/core_ext/string/chr.rb +6 -0
  39. data/lib/asciidoctor/core_ext/symbol/length.rb +6 -0
  40. data/lib/asciidoctor/document.rb +590 -304
  41. data/lib/asciidoctor/extensions.rb +1100 -308
  42. data/lib/asciidoctor/helpers.rb +109 -46
  43. data/lib/asciidoctor/inline.rb +16 -9
  44. data/lib/asciidoctor/list.rb +23 -15
  45. data/lib/asciidoctor/opal_ext.rb +4 -0
  46. data/lib/asciidoctor/opal_ext/comparable.rb +38 -0
  47. data/lib/asciidoctor/opal_ext/dir.rb +13 -0
  48. data/lib/asciidoctor/opal_ext/error.rb +2 -0
  49. data/lib/asciidoctor/opal_ext/file.rb +125 -0
  50. data/lib/asciidoctor/{lexer.rb → parser.rb} +646 -455
  51. data/lib/asciidoctor/path_resolver.rb +141 -77
  52. data/lib/asciidoctor/reader.rb +257 -187
  53. data/lib/asciidoctor/section.rb +12 -16
  54. data/lib/asciidoctor/stylesheets.rb +91 -0
  55. data/lib/asciidoctor/substitutors.rb +1548 -0
  56. data/lib/asciidoctor/table.rb +73 -57
  57. data/lib/asciidoctor/timings.rb +39 -0
  58. data/lib/asciidoctor/version.rb +1 -1
  59. data/man/asciidoctor.1 +22 -14
  60. data/man/asciidoctor.adoc +18 -10
  61. data/test/attributes_test.rb +314 -14
  62. data/test/blocks_test.rb +763 -118
  63. data/test/converter_test.rb +352 -0
  64. data/test/document_test.rb +518 -199
  65. data/test/extensions_test.rb +273 -103
  66. data/test/fixtures/asciidoc_index.txt +27 -13
  67. data/test/fixtures/basic-docinfo.xml +1 -1
  68. data/test/fixtures/chapter-a.adoc +3 -0
  69. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +6 -0
  70. data/test/fixtures/docinfo.xml +1 -1
  71. data/test/fixtures/include-file.asciidoc +2 -0
  72. data/test/fixtures/master.adoc +5 -0
  73. data/test/invoker_test.rb +173 -61
  74. data/test/links_test.rb +97 -21
  75. data/test/lists_test.rb +181 -22
  76. data/test/options_test.rb +86 -2
  77. data/test/paragraphs_test.rb +47 -5
  78. data/test/{lexer_test.rb → parser_test.rb} +128 -57
  79. data/test/paths_test.rb +36 -1
  80. data/test/preamble_test.rb +25 -17
  81. data/test/reader_test.rb +404 -249
  82. data/test/sections_test.rb +623 -58
  83. data/test/substitutions_test.rb +609 -132
  84. data/test/tables_test.rb +198 -24
  85. data/test/test_helper.rb +101 -31
  86. data/test/text_test.rb +88 -31
  87. metadata +160 -64
  88. data/Gemfile +0 -12
  89. data/Guardfile +0 -18
  90. data/asciidoctor.gemspec +0 -143
  91. data/lib/asciidoctor/backends/_stylesheets.rb +0 -466
  92. data/lib/asciidoctor/backends/base_template.rb +0 -114
  93. data/lib/asciidoctor/backends/docbook45.rb +0 -774
  94. data/lib/asciidoctor/backends/docbook5.rb +0 -103
  95. data/lib/asciidoctor/backends/html5.rb +0 -1214
  96. data/lib/asciidoctor/renderer.rb +0 -259
  97. data/lib/asciidoctor/substituters.rb +0 -1083
  98. data/test/fixtures/asciidoc.txt +0 -105
  99. data/test/fixtures/ascshort.txt +0 -32
  100. data/test/fixtures/list_elements.asciidoc +0 -10
  101. data/test/renderer_test.rb +0 -162
@@ -1,103 +0,0 @@
1
- require 'asciidoctor/backends/docbook45'
2
- # NOTE once we decide to make DocBook 5 the default, we'll load the files the other way around
3
-
4
- module Asciidoctor
5
-
6
- module DocBook5
7
- class DocumentTemplate < DocBook45::DocumentTemplate
8
- def author indexed = false
9
- <<-EOF
10
- <author>
11
- <personname>
12
- #{tag 'firstname', indexed ? :"firstname_\#{idx}" : :firstname, indexed}
13
- #{tag 'othername', indexed ? :"middlename_\#{idx}" : :middlename, indexed}
14
- #{tag 'surname', indexed ? :"lastname_\#{idx}" : :lastname, indexed}
15
- </personname>
16
- #{tag 'email', indexed ? :"email_\#{idx}" : :email, indexed}
17
- </author>
18
- EOF
19
- end
20
-
21
- def template
22
- @template ||= @eruby.new <<-EOF
23
- <%#encoding:UTF-8%><?xml version="1.0" encoding="UTF-8"?><%
24
- if attr? :toc %>
25
- <?asciidoc-toc?><%
26
- end
27
- if attr? :numbered %>
28
- <?asciidoc-numbered?><%
29
- end
30
- if doctype == 'book' %>
31
- <book xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"<% unless attr? :nolang %> xml:lang="<%= attr :lang, 'en' %>"<% end %>>
32
- <info>
33
- #{docinfo}
34
- </info>
35
- <%= content.chomp %>
36
- </book><%
37
- else %>
38
- <article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"<% unless attr? :nolang %> xml:lang="<%= attr :lang, 'en' %>"<% end %>>
39
- <info>
40
- #{docinfo}
41
- </info>
42
- <%= content.chomp %>
43
- </article><%
44
- end %>
45
- EOF
46
- end
47
- end
48
- class EmbeddedTemplate < DocBook45::EmbeddedTemplate; end
49
- class BlockTocTemplate < DocBook45::BlockTocTemplate; end
50
- class BlockPreambleTemplate < DocBook45::BlockPreambleTemplate; end
51
- class SectionTemplate < DocBook45::SectionTemplate; end
52
- class BlockFloatingTitleTemplate < DocBook45::BlockFloatingTitleTemplate; end
53
- class BlockParagraphTemplate < DocBook45::BlockParagraphTemplate; end
54
- class BlockAdmonitionTemplate < DocBook45::BlockAdmonitionTemplate; end
55
- class BlockUlistTemplate < DocBook45::BlockUlistTemplate; end
56
- class BlockOlistTemplate < DocBook45::BlockOlistTemplate; end
57
- class BlockColistTemplate < DocBook45::BlockColistTemplate; end
58
- class BlockDlistTemplate < DocBook45::BlockDlistTemplate; end
59
- class BlockOpenTemplate < DocBook45::BlockOpenTemplate; end
60
- class BlockListingTemplate < DocBook45::BlockListingTemplate; end
61
- class BlockLiteralTemplate < DocBook45::BlockLiteralTemplate; end
62
- class BlockExampleTemplate < DocBook45::BlockExampleTemplate; end
63
- class BlockSidebarTemplate < DocBook45::BlockSidebarTemplate; end
64
- class BlockQuoteTemplate < DocBook45::BlockQuoteTemplate; end
65
- class BlockVerseTemplate < DocBook45::BlockVerseTemplate; end
66
- class BlockPassTemplate < DocBook45::BlockPassTemplate; end
67
- class BlockTableTemplate < DocBook45::BlockTableTemplate; end
68
- class BlockImageTemplate < DocBook45::BlockImageTemplate; end
69
- class BlockAudioTemplate < DocBook45::BlockAudioTemplate; end
70
- class BlockVideoTemplate < DocBook45::BlockVideoTemplate; end
71
- class BlockRulerTemplate < DocBook45::BlockRulerTemplate; end
72
- class BlockPageBreakTemplate < DocBook45::BlockPageBreakTemplate; end
73
- class InlineBreakTemplate < DocBook45::InlineBreakTemplate; end
74
- class InlineQuotedTemplate < DocBook45::InlineQuotedTemplate; end
75
- class InlineButtonTemplate < DocBook45::InlineButtonTemplate; end
76
- class InlineKbdTemplate < DocBook45::InlineKbdTemplate; end
77
- class InlineMenuTemplate < DocBook45::InlineMenuTemplate; end
78
- class InlineAnchorTemplate < DocBook45::InlineAnchorTemplate
79
- def anchor(target, text, type, node)
80
- case type
81
- when :ref
82
- %(<anchor#{common_attrs target, nil, text}/>)
83
- when :xref
84
- if node.attr? 'path', nil
85
- linkend = (node.attr 'fragment') || target
86
- text.nil? ? %(<xref linkend="#{linkend}"/>) : %(<link linkend="#{linkend}">#{text}</link>)
87
- else
88
- text = text || (node.attr 'path')
89
- %(<link xlink:href="#{target}">#{text}</link>)
90
- end
91
- when :link
92
- %(<link xlink:href="#{target}">#{text}</link>)
93
- when :bibref
94
- %(<anchor#{common_attrs target, nil, "[#{target}]"}/>[#{target}])
95
- end
96
- end
97
- end
98
- class InlineImageTemplate < DocBook45::InlineImageTemplate; end
99
- class InlineFootnoteTemplate < DocBook45::InlineFootnoteTemplate; end
100
- class InlineCalloutTemplate < DocBook45::InlineCalloutTemplate; end
101
- class InlineIndextermTemplate < DocBook45::InlineIndextermTemplate; end
102
- end # module DocBook5
103
- end # module Asciidoctor
@@ -1,1214 +0,0 @@
1
- require 'asciidoctor/backends/_stylesheets'
2
-
3
- module Asciidoctor
4
- module HTML5
5
-
6
- class DocumentTemplate < BaseTemplate
7
- def self.outline(node, to_depth = 2)
8
- toc_level_buffer = []
9
- sections = node.sections
10
- unless sections.empty?
11
- # FIXME the level for special sections should be set correctly in the model
12
- # sec_level will only be 0 if we have a book doctype with parts
13
- sec_level = sections.first.level
14
- if sec_level == 0 && sections.first.special
15
- sec_level = 1
16
- end
17
- toc_level_buffer << %(<ul class="sectlevel#{sec_level}">)
18
- sections.each do |section|
19
- section_num = section.numbered ? %(#{section.sectnum} ) : nil
20
- toc_level_buffer << %(<li><a href=\"##{section.id}\">#{section_num}#{section.captioned_title}</a></li>)
21
- if section.level < to_depth && (child_toc_level = outline(section, to_depth)) != ''
22
- toc_level_buffer << '<li>'
23
- toc_level_buffer << child_toc_level
24
- toc_level_buffer << '</li>'
25
- end
26
- end
27
- toc_level_buffer << '</ul>'
28
- end
29
- toc_level_buffer * EOL
30
- end
31
-
32
- def template
33
- @template ||= @eruby.new <<-EOS
34
- <%#encoding:UTF-8%><!DOCTYPE html>
35
- <html<%= (attr? 'nolang') ? nil : %( lang="\#{attr 'lang', 'en'}") %>>
36
- <head>
37
- <meta http-equiv="Content-Type" content="text/html; charset=<%= attr :encoding %>">
38
- <meta name="generator" content="Asciidoctor <%= attr 'asciidoctor-version' %>">
39
- <meta name="viewport" content="width=device-width, initial-scale=1.0"><%
40
- if attr? :description %>
41
- <meta name="description" content="<%= attr :description %>"><%
42
- end
43
- if attr? :keywords %>
44
- <meta name="keywords" content="<%= attr :keywords %>"><%
45
- end %>
46
- <title><%= doctitle(:sanitize => true) || (attr 'untitled-label') %></title><%
47
- if DEFAULT_STYLESHEET_KEYS.include?(attr 'stylesheet')
48
- if @safe >= SafeMode::SECURE || (attr? 'linkcss') %>
49
- <link rel="stylesheet" href="<%= normalize_web_path(DEFAULT_STYLESHEET_NAME, (attr :stylesdir, '')) %>"><%
50
- else %>
51
- <style>
52
- <%= HTML5.default_asciidoctor_stylesheet %>
53
- </style><%
54
- end
55
- elsif attr? :stylesheet
56
- if @safe >= SafeMode::SECURE || (attr? 'linkcss') %>
57
- <link rel="stylesheet" href="<%= normalize_web_path((attr :stylesheet), (attr :stylesdir, '')) %>"><%
58
- else %>
59
- <style>
60
- <%= read_asset normalize_system_path((attr :stylesheet), (attr :stylesdir, '')), true %>
61
- </style><%
62
- end
63
- end
64
- if attr? 'icons', 'font'
65
- if !(attr 'iconfont-remote', '').nil? %>
66
- <link rel="stylesheet" href="<%= attr 'iconfont-cdn', 'http://cdnjs.cloudflare.com/ajax/libs/font-awesome/3.2.1/css/font-awesome.min.css' %>"><%
67
- else %>
68
- <link rel="stylesheet" href="<%= normalize_web_path(%(\#{attr 'iconfont-name', 'font-awesome'}.css), (attr 'stylesdir', '')) %>"><%
69
- end
70
- end
71
- case attr 'source-highlighter'
72
- when 'coderay'
73
- if (attr 'coderay-css', 'class') == 'class'
74
- if @safe >= SafeMode::SECURE || (attr? 'linkcss') %>
75
- <link rel="stylesheet" href="<%= normalize_web_path('asciidoctor-coderay.css', (attr :stylesdir, '')) %>"><%
76
- else %>
77
- <style>
78
- <%= HTML5.default_coderay_stylesheet %>
79
- </style><%
80
- end
81
- end
82
- when 'pygments'
83
- if (attr 'pygments-css', 'class') == 'class'
84
- if @safe >= SafeMode::SECURE || (attr? 'linkcss') %>
85
- <link rel="stylesheet" href="<%= normalize_web_path('asciidoctor-pygments.css', (attr :stylesdir, '')) %>"><%
86
- else %>
87
- <style>
88
- <%= HTML5.pygments_stylesheet(attr 'pygments-style') %>
89
- </style><%
90
- end
91
- end
92
- when 'highlightjs', 'highlight.js' %>
93
- <link rel="stylesheet" href="<%= attr :highlightjsdir, 'http://cdnjs.cloudflare.com/ajax/libs/highlight.js/7.3' %>/styles/<%= attr 'highlightjs-theme', 'default' %>.min.css">
94
- <script src="<%= attr :highlightjsdir, 'http://cdnjs.cloudflare.com/ajax/libs/highlight.js/7.3' %>/highlight.min.js"></script>
95
- <script>hljs.initHighlightingOnLoad()</script><%
96
- when 'prettify' %>
97
- <link rel="stylesheet" href="<%= attr 'prettifydir', 'http://cdnjs.cloudflare.com/ajax/libs/prettify/r298' %>/<%= attr 'prettify-theme', 'prettify' %>.min.css">
98
- <script src="<%= attr 'prettifydir', 'http://cdnjs.cloudflare.com/ajax/libs/prettify/r298' %>/prettify.min.js"></script>
99
- <script>document.addEventListener('DOMContentLoaded', prettyPrint)</script><%
100
- end %><%= (docinfo_content = docinfo).empty? ? nil : %(
101
- \#{docinfo_content}) %>
102
- </head>
103
- <body<%= @id ? %( id="\#{@id}") : nil %> class="<%= doctype %><%= (attr? 'toc-class') && (attr? 'toc') && (attr? 'toc-placement', 'auto') ? %( \#{attr 'toc-class'} toc-\#{attr 'toc-position', 'left'}) : nil %>"<%= (attr? 'max-width') ? %( style="max-width: \#{attr 'max-width'};") : nil %>><%
104
- unless noheader %>
105
- <div id="header"><%
106
- if doctype == 'manpage' %>
107
- <h1><%= doctitle %> Manual Page</h1><%
108
- if (attr? :toc) && (attr? 'toc-placement', 'auto') %>
109
- <div id="toc" class="<%= attr 'toc-class', 'toc' %>">
110
- <div id="toctitle"><%= attr 'toc-title' %></div>
111
- <%= template.class.outline(self, (attr :toclevels, 2).to_i) %>
112
- </div><%
113
- end %>
114
- <h2><%= attr 'manname-title' %></h2>
115
- <div class="sectionbody">
116
- <p><%= %(\#{attr 'manname'} - \#{attr 'manpurpose'}) %></p>
117
- </div><%
118
- else
119
- if has_header?
120
- unless notitle %>
121
- <h1><%= @header.title %></h1><%
122
- end %><%
123
- if attr? :author %>
124
- <span id="author" class="author"><%= attr :author %></span><br><%
125
- if attr? :email %>
126
- <span id="email" class="email"><%= sub_macros(attr :email) %></span><br><%
127
- end
128
- if (authorcount = (attr :authorcount).to_i) > 1
129
- (2..authorcount).each do |idx| %><span id="author<%= idx %>" class="author"><%= attr "author_\#{idx}" %></span><br><%
130
- if attr? "email_\#{idx}" %>
131
- <span id="email<%= idx %>" class="email"><%= sub_macros(attr "email_\#{idx}") %></span><br><%
132
- end
133
- end
134
- end
135
- end
136
- if attr? :revnumber %>
137
- <span id="revnumber"><%= ((attr 'version-label') || '').downcase %> <%= attr :revnumber %><%= (attr? :revdate) ? ',' : '' %></span><%
138
- end
139
- if attr? :revdate %>
140
- <span id="revdate"><%= attr :revdate %></span><%
141
- end
142
- if attr? :revremark %>
143
- <br><span id="revremark"><%= attr :revremark %></span><%
144
- end
145
- end
146
- if (attr? :toc) && (attr? 'toc-placement', 'auto') %>
147
- <div id="toc" class="<%= attr 'toc-class', 'toc' %>">
148
- <div id="toctitle"><%= attr 'toc-title' %></div>
149
- <%= template.class.outline(self, (attr :toclevels, 2).to_i) %>
150
- </div><%
151
- end
152
- end %>
153
- </div><%
154
- end %>
155
- <div id="content">
156
- <%= content %>
157
- </div><%
158
- unless !footnotes? || (attr? :nofootnotes) %>
159
- <div id="footnotes">
160
- <hr><%
161
- footnotes.each do |fn| %>
162
- <div class="footnote" id="_footnote_<%= fn.index %>">
163
- <a href="#_footnoteref_<%= fn.index %>"><%= fn.index %></a>. <%= fn.text %>
164
- </div><%
165
- end %>
166
- </div><%
167
- end %>
168
- <div id="footer">
169
- <div id="footer-text"><%
170
- if attr? :revnumber %>
171
- <%= %(\#{attr 'version-label'} \#{attr :revnumber}) %><br><%
172
- end
173
- if attr? 'last-update-label' %>
174
- <%= %(\#{attr 'last-update-label'} \#{attr :docdatetime}) %><%
175
- end %>
176
- </div><%= (docinfo_content = docinfo :footer).empty? ? nil : %(
177
- \#{docinfo_content}) %>
178
- </div>
179
- </body>
180
- </html>
181
- EOS
182
- end
183
- end
184
-
185
- class EmbeddedTemplate < BaseTemplate
186
- def result(node)
187
- result_buffer = []
188
- if !node.notitle && node.has_header?
189
- id_attr = node.id ? %( id="#{node.id}") : nil
190
- result_buffer << %(<h1#{id_attr}>#{node.header.title}</h1>)
191
- end
192
-
193
- result_buffer << node.content
194
-
195
- if node.footnotes? && !(node.attr? 'nofootnotes')
196
- result_buffer << '<div id="footnotes">'
197
- result_buffer << '<hr>'
198
- node.footnotes.each do |footnote|
199
- result_buffer << %(<div class="footnote" id="_footnote_#{footnote.index}">
200
- <a href="#_footnoteref_#{footnote.index}">#{footnote.index}</a> #{footnote.text}
201
- </div>)
202
- end
203
-
204
- result_buffer << '</div>'
205
- end
206
-
207
- result_buffer * EOL
208
- end
209
-
210
- def template
211
- :invoke_result
212
- end
213
- end
214
-
215
- class BlockTocTemplate < BaseTemplate
216
- def result(node)
217
- doc = node.document
218
-
219
- return '' unless (doc.attr? 'toc')
220
-
221
- if node.id
222
- id_attr = %( id="#{node.id}")
223
- title_id_attr = ''
224
- elsif doc.embedded? || !(doc.attr? 'toc-placement')
225
- id_attr = ' id="toc"'
226
- title_id_attr = ' id="toctitle"'
227
- else
228
- id_attr = ''
229
- title_id_attr = ''
230
- end
231
- title = node.title? ? node.title : (doc.attr 'toc-title')
232
- levels = (node.attr? 'levels') ? (node.attr 'levels').to_i : (doc.attr 'toclevels', 2).to_i
233
- role = node.role? ? node.role : (doc.attr 'toc-class', 'toc')
234
-
235
- %(<div#{id_attr} class="#{role}">
236
- <div#{title_id_attr} class="title">#{title}</div>
237
- #{DocumentTemplate.outline(doc, levels)}
238
- </div>\n)
239
- end
240
-
241
- def template
242
- :invoke_result
243
- end
244
- end
245
-
246
- class BlockPreambleTemplate < BaseTemplate
247
- def toc(node)
248
- if (node.attr? 'toc') && (node.attr? 'toc-placement', 'preamble')
249
- %(\n<div id="toc" class="#{node.attr 'toc-class', 'toc'}">
250
- <div id="toctitle">#{node.attr 'toc-title'}</div>
251
- #{DocumentTemplate.outline(node.document, (node.attr 'toclevels', 2).to_i)}
252
- </div>)
253
- else
254
- ''
255
- end
256
- end
257
-
258
- def result(node)
259
- %(<div id="preamble">
260
- <div class="sectionbody">
261
- #{node.content}
262
- </div>#{toc node}
263
- </div>)
264
- end
265
-
266
- def template
267
- :invoke_result
268
- end
269
- end
270
-
271
- class SectionTemplate < BaseTemplate
272
- def result(sec)
273
- slevel = sec.level
274
- # QUESTION should this check be done in section?
275
- if slevel == 0 && sec.special
276
- slevel = 1
277
- end
278
- htag = "h#{slevel + 1}"
279
- id = anchor = link_start = link_end = nil
280
- if sec.id
281
- id = %( id="#{sec.id}")
282
- if sec.document.attr? 'sectanchors'
283
- #if sec.document.attr? 'icons', 'font'
284
- # anchor = %(<a class="anchor" href="##{sec.id}"><i class="icon-anchor"></i></a>)
285
- #else
286
- anchor = %(<a class="anchor" href="##{sec.id}"></a>)
287
- #end
288
- elsif sec.document.attr? 'sectlinks'
289
- link_start = %(<a class="link" href="##{sec.id}">)
290
- link_end = '</a>'
291
- end
292
- end
293
-
294
- if slevel == 0
295
- %(<h1#{id} class="sect0">#{anchor}#{link_start}#{sec.title}#{link_end}</h1>
296
- #{sec.content})
297
- else
298
- role = sec.role? ? " #{sec.role}" : nil
299
- if sec.numbered
300
- sectnum = "#{sec.sectnum} "
301
- else
302
- sectnum = nil
303
- end
304
-
305
- if slevel == 1
306
- content = %(<div class="sectionbody">
307
- #{sec.content}
308
- </div>)
309
- else
310
- content = sec.content
311
- end
312
- %(<div class="sect#{slevel}#{role}">
313
- <#{htag}#{id}>#{anchor}#{link_start}#{sectnum}#{sec.captioned_title}#{link_end}</#{htag}>
314
- #{content}
315
- </div>)
316
- end
317
- end
318
-
319
- def template
320
- :invoke_result
321
- end
322
- end
323
-
324
- class BlockFloatingTitleTemplate < BaseTemplate
325
- def result(node)
326
- tag_name = "h#{node.level + 1}"
327
- id_attribute = node.id ? %( id="#{node.id}") : nil
328
- classes = [node.style, node.role].compact
329
- %(<#{tag_name}#{id_attribute} class="#{classes * ' '}">#{node.title}</#{tag_name}>)
330
- end
331
-
332
- def template
333
- :invoke_result
334
- end
335
- end
336
-
337
- class BlockDlistTemplate < BaseTemplate
338
- def result(node)
339
- result_buffer = []
340
- id_attribute = node.id ? %( id="#{node.id}") : nil
341
-
342
- case node.style
343
- when 'qanda'
344
- classes = ['qlist', node.style, node.role].compact
345
- when 'horizontal'
346
- classes = ['hdlist', node.role].compact
347
- else
348
- classes = ['dlist', node.style, node.role].compact
349
- end
350
-
351
- class_attribute = %( class="#{classes * ' '}")
352
-
353
- result_buffer << %(<div#{id_attribute}#{class_attribute}>)
354
- result_buffer << %(<div class="title">#{node.title}</div>) if node.title?
355
- case node.style
356
- when 'qanda'
357
- result_buffer << '<ol>'
358
- node.items.each do |terms, dd|
359
- result_buffer << '<li>'
360
- [*terms].each do |dt|
361
- result_buffer << %(<p><em>#{dt.text}</em></p>)
362
- end
363
- unless dd.nil?
364
- result_buffer << %(<p>#{dd.text}</p>) if dd.text?
365
- result_buffer << dd.content if dd.blocks?
366
- end
367
- result_buffer << '</li>'
368
- end
369
- result_buffer << '</ol>'
370
- when 'horizontal'
371
- result_buffer << '<table>'
372
- if (node.attr? 'labelwidth') || (node.attr? 'itemwidth')
373
- result_buffer << '<colgroup>'
374
- col_style_attribute = (node.attr? 'labelwidth') ? %( style="width:#{(node.attr 'labelwidth').chomp '%'}%;") : nil
375
- result_buffer << %(<col#{col_style_attribute}>)
376
- col_style_attribute = (node.attr? 'itemwidth') ? %( style="width:#{(node.attr 'itemwidth').chomp '%'}%;") : nil
377
- result_buffer << %(<col#{col_style_attribute}>)
378
- result_buffer << '</colgroup>'
379
- end
380
- node.items.each do |terms, dd|
381
- result_buffer << '<tr>'
382
- result_buffer << %(<td class="hdlist1#{(node.option? 'strong') ? ' strong' : nil}">)
383
- terms_array = [*terms]
384
- last_term = terms_array.last
385
- terms_array.each do |dt|
386
- result_buffer << dt.text
387
- result_buffer << '<br>' if dt != last_term
388
- end
389
- result_buffer << '</td>'
390
- result_buffer << '<td class="hdlist2">'
391
- unless dd.nil?
392
- result_buffer << %(<p>#{dd.text}</p>) if dd.text?
393
- result_buffer << dd.content if dd.blocks?
394
- end
395
- result_buffer << '</td>'
396
- result_buffer << '</tr>'
397
- end
398
- result_buffer << '</table>'
399
- else
400
- result_buffer << '<dl>'
401
- dt_style_attribute = node.style.nil? ? ' class="hdlist1"' : nil
402
- node.items.each do |terms, dd|
403
- [*terms].each do |dt|
404
- result_buffer << %(<dt#{dt_style_attribute}>#{dt.text}</dt>)
405
- end
406
- unless dd.nil?
407
- result_buffer << '<dd>'
408
- result_buffer << %(<p>#{dd.text}</p>) if dd.text?
409
- result_buffer << dd.content if dd.blocks?
410
- result_buffer << '</dd>'
411
- end
412
- end
413
- result_buffer << '</dl>'
414
- end
415
-
416
- result_buffer << '</div>'
417
- result_buffer * EOL
418
- end
419
-
420
- def template
421
- :invoke_result
422
- end
423
- end
424
-
425
- class BlockListingTemplate < BaseTemplate
426
- def result(node)
427
- nowrap = (!node.document.attr? 'prewrap') || (node.option? 'nowrap')
428
- if node.style == 'source'
429
- language = node.attr 'language'
430
- language_classes = language ? %(#{language} language-#{language}) : nil
431
- case node.attr 'source-highlighter'
432
- when 'coderay'
433
- pre_class = nowrap ? ' class="CodeRay nowrap"' : ' class="CodeRay"'
434
- code_class = language ? %( class="#{language_classes}") : nil
435
- when 'pygments'
436
- pre_class = nowrap ? ' class="pygments highlight nowrap"' : ' class="pygments highlight"'
437
- code_class = language ? %( class="#{language_classes}") : nil
438
- when 'highlightjs', 'highlight.js'
439
- pre_class = nowrap ? ' class="highlight nowrap"' : ' class="highlight"'
440
- code_class = language ? %( class="#{language_classes}") : nil
441
- when 'prettify'
442
- pre_class = %( class="prettyprint#{nowrap ? ' nowrap' : nil}#{(node.attr? 'linenums') ? ' linenums' : nil})
443
- pre_class = language ? %(#{pre_class} #{language_classes}") : %(#{pre_class}")
444
- code_class = nil
445
- when 'html-pipeline'
446
- pre_class = language ? %( lang="#{language}") : nil
447
- code_class = nil
448
- else
449
- pre_class = nowrap ? ' class="highlight nowrap"' : ' class="highlight"'
450
- code_class = language ? %( class="#{language_classes}") : nil
451
- end
452
- pre = %(<pre#{pre_class}><code#{code_class}>#{preserve_endlines(node.content, node)}</code></pre>)
453
- else
454
- pre = %(<pre#{nowrap ? ' class="nowrap"' : nil}>#{preserve_endlines(node.content, node)}</pre>)
455
- end
456
-
457
- %(<div#{node.id && " id=\"#{node.id}\""} class="listingblock#{node.role && " #{node.role}"}">#{node.title? ? "
458
- <div class=\"title\">#{node.captioned_title}</div>" : nil}
459
- <div class="content">
460
- #{pre}
461
- </div>
462
- </div>)
463
- end
464
-
465
- def template
466
- :invoke_result
467
- end
468
- end
469
-
470
- class BlockLiteralTemplate < BaseTemplate
471
- def result(node)
472
- nowrap = (!node.document.attr? 'prewrap') || (node.option? 'nowrap')
473
- %(<div#{node.id && " id=\"#{node.id}\""} class="literalblock#{node.role && " #{node.role}"}">#{node.title? ? "
474
- <div class=\"title\">#{node.title}</div>" : nil}
475
- <div class="content">
476
- <pre#{nowrap ? ' class="nowrap"' : nil}>#{preserve_endlines(node.content, node)}</pre>
477
- </div>
478
- </div>)
479
- end
480
-
481
- def template
482
- :invoke_result
483
- end
484
- end
485
-
486
- class BlockAdmonitionTemplate < BaseTemplate
487
- def result(node)
488
- id = node.id
489
- name = node.attr 'name'
490
- role = node.role
491
- title = node.title? ? node.title : nil
492
- if node.document.attr? 'icons'
493
- if node.document.attr? 'icons', 'font'
494
- caption = %(<i class="icon-#{name}" title="#{node.caption}"></i>)
495
- else
496
- caption = %(<img src="#{node.icon_uri(name)}" alt="#{node.caption}">)
497
- end
498
- else
499
- caption = %(<div class="title">#{node.caption}</div>)
500
- end
501
- %(<div#{id && " id=\"#{id}\""} class="admonitionblock #{name}#{role && " #{role}"}">
502
- <table>
503
- <tr>
504
- <td class="icon">
505
- #{caption}
506
- </td>
507
- <td class="content">#{title ? "
508
- <div class=\"title\">#{title}</div>" : nil}
509
- #{node.content}
510
- </td>
511
- </tr>
512
- </table>
513
- </div>)
514
- end
515
-
516
- def template
517
- :invoke_result
518
- end
519
- end
520
-
521
- class BlockParagraphTemplate < BaseTemplate
522
- def result(node)
523
- id_attribute = node.id ? %( id="#{node.id}") : nil
524
- title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : nil
525
-
526
- %(<div#{id_attribute} class="#{!node.role? ? 'paragraph' : ['paragraph', node.role] * ' '}">
527
- #{title_element}<p>#{node.content}</p>
528
- </div>)
529
- end
530
-
531
- def template
532
- :invoke_result
533
- end
534
- end
535
-
536
- class BlockSidebarTemplate < BaseTemplate
537
- def result(node)
538
- id_attribute = node.id ? %( id="#{node.id}") : nil
539
- title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : nil
540
-
541
- %(<div#{id_attribute} class="#{!node.role? ? 'sidebarblock' : ['sidebarblock', node.role] * ' '}">
542
- <div class="content">
543
- #{title_element}#{node.content}
544
- </div>
545
- </div>)
546
- end
547
-
548
- def template
549
- :invoke_result
550
- end
551
- end
552
-
553
- class BlockExampleTemplate < BaseTemplate
554
- def result(node)
555
- id_attribute = node.id ? %( id="#{node.id}") : nil
556
- title_element = node.title? ? %(<div class="title">#{node.captioned_title}</div>\n) : nil
557
-
558
- %(<div#{id_attribute} class="#{!node.role? ? 'exampleblock' : ['exampleblock', node.role] * ' '}">
559
- #{title_element}<div class="content">
560
- #{node.content}
561
- </div>
562
- </div>)
563
- end
564
-
565
- def template
566
- :invoke_result
567
- end
568
- end
569
-
570
- class BlockOpenTemplate < BaseTemplate
571
- def result(node)
572
- open_block(node, node.id, node.style, node.role, node.title? ? node.title : nil, node.content)
573
- end
574
-
575
- def open_block(node, id, style, role, title, content)
576
- if style == 'abstract'
577
- if node.parent == node.document && node.document.doctype == 'book'
578
- warn 'asciidoctor: WARNING: abstract block cannot be used in a document without a title when doctype is book. Excluding block content.'
579
- ''
580
- else
581
- %(<div#{id && " id=\"#{id}\""} class="quoteblock abstract#{role && " #{role}"}">#{title &&
582
- "<div class=\"title\">#{title}</div>"}
583
- <blockquote>
584
- #{content}
585
- </blockquote>
586
- </div>)
587
- end
588
- elsif style == 'partintro' && (node.level != 0 || node.parent.context != :section || node.document.doctype != 'book')
589
- warn 'asciidoctor: ERROR: partintro block can only be used when doctype is book and it\'s a child of a book part. Excluding block content.'
590
- ''
591
- else
592
- %(<div#{id && " id=\"#{id}\""} class="openblock#{style != 'open' ? " #{style}" : ''}#{role && " #{role}"}">#{title &&
593
- "<div class=\"title\">#{title}</div>"}
594
- <div class="content">
595
- #{content}
596
- </div>
597
- </div>)
598
- end
599
- end
600
-
601
- def template
602
- :invoke_result
603
- end
604
- end
605
-
606
- class BlockPassTemplate < BaseTemplate
607
- def template
608
- :content
609
- end
610
- end
611
-
612
- class BlockQuoteTemplate < BaseTemplate
613
- def result(node)
614
- id_attribute = node.id ? %( id="#{node.id}") : nil
615
- classes = ['quoteblock', node.role].compact
616
- class_attribute = %( class="#{classes * ' '}")
617
- title_element = node.title? ? %(\n<div class="title">#{node.title}</div>) : nil
618
- attribution = (node.attr? 'attribution') ? (node.attr 'attribution') : nil
619
- citetitle = (node.attr? 'citetitle') ? (node.attr 'citetitle') : nil
620
- if attribution || citetitle
621
- cite_element = citetitle ? %(<cite>#{citetitle}</cite>) : nil
622
- attribution_text = attribution ? %(#{citetitle ? "<br>\n" : nil}&#8212; #{attribution}) : nil
623
- attribution_element = %(\n<div class="attribution">\n#{cite_element}#{attribution_text}\n</div>)
624
- else
625
- attribution_element = nil
626
- end
627
-
628
- %(<div#{id_attribute}#{class_attribute}>#{title_element}
629
- <blockquote>
630
- #{node.content}
631
- </blockquote>#{attribution_element}
632
- </div>)
633
- end
634
-
635
- def template
636
- :invoke_result
637
- end
638
- end
639
-
640
- class BlockVerseTemplate < BaseTemplate
641
- def result(node)
642
- id_attribute = node.id ? %( id="#{node.id}") : nil
643
- classes = ['verseblock', node.role].compact
644
- class_attribute = %( class="#{classes * ' '}")
645
- title_element = node.title? ? %(\n<div class="title">#{node.title}</div>) : nil
646
- attribution = (node.attr? 'attribution') ? (node.attr 'attribution') : nil
647
- citetitle = (node.attr? 'citetitle') ? (node.attr 'citetitle') : nil
648
- if attribution || citetitle
649
- cite_element = citetitle ? %(<cite>#{citetitle}</cite>) : nil
650
- attribution_text = attribution ? %(#{citetitle ? "<br>\n" : nil}&#8212; #{attribution}) : nil
651
- attribution_element = %(\n<div class="attribution">\n#{cite_element}#{attribution_text}\n</div>)
652
- else
653
- attribution_element = nil
654
- end
655
-
656
- %(<div#{id_attribute}#{class_attribute}>#{title_element}
657
- <pre class="content">#{preserve_endlines node.content, node}</pre>#{attribution_element}
658
- </div>)
659
- end
660
-
661
- def template
662
- :invoke_result
663
- end
664
- end
665
-
666
- class BlockUlistTemplate < BaseTemplate
667
- def result(node)
668
- result_buffer = []
669
- id_attribute = node.id ? %( id="#{node.id}") : nil
670
- div_classes = ['ulist', node.style, node.role].compact
671
- marker_checked = nil
672
- marker_unchecked = nil
673
- if (checklist = (node.option? 'checklist'))
674
- div_classes.insert(1, 'checklist')
675
- ul_class_attribute = ' class="checklist"'
676
- if node.option? 'interactive'
677
- marker_checked = %(<input type="checkbox" data-item-complete="1" checked> )
678
- marker_unchecked = %(<input type="checkbox" data-item-complete="0"> )
679
- else
680
- if node.document.attr? 'icons', 'font'
681
- marker_checked = '<i class="icon-check"></i> '
682
- marker_unchecked = '<i class="icon-check-empty"></i> '
683
- else
684
- # could use &#9745 (checked ballot) and &#9744 (ballot) w/o font instead
685
- marker_checked = %(<input type="checkbox" data-item-complete="1" checked disabled> )
686
- marker_unchecked = %(<input type="checkbox" data-item-complete="0" disabled> )
687
- end
688
- end
689
- elsif !node.style.nil?
690
- ul_class_attribute = %( class="#{node.style}")
691
- else
692
- ul_class_attribute = nil
693
- end
694
- div_class_attribute = %( class="#{div_classes * ' '}")
695
- result_buffer << %(<div#{id_attribute}#{div_class_attribute}>)
696
- result_buffer << %(<div class="title">#{node.title}</div>) if node.title?
697
- result_buffer << %(<ul#{ul_class_attribute}>)
698
-
699
- node.items.each do |item|
700
- if checklist && (item.attr? 'checkbox')
701
- marker = (item.attr? 'checked') ? marker_checked : marker_unchecked
702
- else
703
- marker = nil
704
- end
705
- result_buffer << '<li>'
706
- result_buffer << %(<p>#{marker}#{item.text}</p>)
707
- result_buffer << item.content if item.blocks?
708
- result_buffer << '</li>'
709
- end
710
-
711
- result_buffer << '</ul>'
712
- result_buffer << '</div>'
713
-
714
- result_buffer * EOL
715
- end
716
-
717
- def template
718
- :invoke_result
719
- end
720
- end
721
-
722
- class BlockOlistTemplate < BaseTemplate
723
- def result(node)
724
- result_buffer = []
725
- id_attribute = node.id ? %( id="#{node.id}") : nil
726
- classes = ['olist', node.style, node.role].compact
727
- class_attribute = %( class="#{classes * ' '}")
728
-
729
- result_buffer << %(<div#{id_attribute}#{class_attribute}>)
730
- result_buffer << %(<div class="title">#{node.title}</div>) if node.title?
731
-
732
- type_attribute = (keyword = node.list_marker_keyword) ? %( type="#{keyword}") : nil
733
- start_attribute = (node.attr? 'start') ? %( start="#{node.attr 'start'}") : nil
734
- result_buffer << %(<ol class="#{node.style}"#{type_attribute}#{start_attribute}>)
735
-
736
- node.items.each do |item|
737
- result_buffer << '<li>'
738
- result_buffer << %(<p>#{item.text}</p>)
739
- result_buffer << item.content if item.blocks?
740
- result_buffer << '</li>'
741
- end
742
-
743
- result_buffer << '</ol>'
744
- result_buffer << '</div>'
745
-
746
- result_buffer * EOL
747
- end
748
-
749
- def template
750
- :invoke_result
751
- end
752
- end
753
-
754
- class BlockColistTemplate < BaseTemplate
755
- def result(node)
756
- result_buffer = []
757
- id_attribute = node.id ? %( id="#{node.id}") : nil
758
- classes = ['colist', node.style, node.role].compact
759
- class_attribute = %( class="#{classes * ' '}")
760
-
761
- result_buffer << %(<div#{id_attribute}#{class_attribute}>)
762
- result_buffer << %(<div class="title">#{node.title}</div>) if node.title?
763
-
764
- if node.document.attr? 'icons'
765
- result_buffer << '<table>'
766
-
767
- font_icons = node.document.attr? 'icons', 'font'
768
- node.items.each_with_index do |item, i|
769
- num = i + 1
770
- num_element = font_icons ?
771
- %(<i class="conum" data-value="#{num}"></i><b>#{num}</b>) :
772
- %(<img src="#{node.icon_uri "callouts/#{num}"}" alt="#{num}">)
773
- result_buffer << %(<tr>
774
- <td>#{num_element}</td>
775
- <td>#{item.text}</td>
776
- </tr>)
777
- end
778
-
779
- result_buffer << '</table>'
780
- else
781
- result_buffer << '<ol>'
782
- node.items.each do |item|
783
- result_buffer << %(<li>
784
- <p>#{item.text}</p>
785
- </li>)
786
- end
787
- result_buffer << '</ol>'
788
- end
789
-
790
- result_buffer << '</div>'
791
- result_buffer * EOL
792
- end
793
-
794
- def template
795
- :invoke_result
796
- end
797
- end
798
-
799
- class BlockTableTemplate < BaseTemplate
800
- def template
801
- @template ||= @eruby.new <<-EOS
802
- <%#encoding:UTF-8%><table<%= @id ? %( id="\#{@id}") : nil %> class="tableblock frame-<%= attr :frame, 'all' %> grid-<%= attr :grid, 'all'%><%= role? ? " \#{role}" : nil %>" style="<%
803
- if !(option? 'autowidth') %>width:<%= attr :tablepcwidth %>%; <% end %><%
804
- if attr? :float %>float: <%= attr :float %>; <% end %>"><%
805
- if title? %>
806
- <caption class="title"><%= captioned_title %></caption><%
807
- end
808
- if (attr :rowcount) >= 0 %>
809
- <colgroup><%
810
- if option? 'autowidth'
811
- @columns.each do %>
812
- <col><%
813
- end
814
- else
815
- @columns.each do |col| %>
816
- <col style="width:<%= col.attr :colpcwidth %>%;"><%
817
- end
818
- end %>
819
- </colgroup><%
820
- [:head, :foot, :body].select {|tsec| !@rows[tsec].empty? }.each do |tsec| %>
821
- <t<%= tsec %>><%
822
- @rows[tsec].each do |row| %>
823
- <tr><%
824
- row.each do |cell| %>
825
- <<%= tsec == :head ? 'th' : 'td' %> class="tableblock halign-<%= cell.attr :halign %> valign-<%= cell.attr :valign %>"#{attribute('colspan', 'cell.colspan')}#{attribute('rowspan', 'cell.rowspan')}<%
826
- cell_content = ''
827
- if tsec == :head
828
- cell_content = cell.text
829
- else
830
- case cell.style
831
- when :asciidoc
832
- cell_content = %(<div>\#{cell.content}</div>)
833
- when :verse
834
- cell_content = %(<div class="verse">\#{template.preserve_endlines(cell.text, self)}</div>)
835
- when :literal
836
- cell_content = %(<div class="literal"><pre>\#{template.preserve_endlines(cell.text, self)}</pre></div>)
837
- when :header
838
- cell.content.each do |text|
839
- cell_content = %(\#{cell_content}<p class="tableblock header">\#{text}</p>)
840
- end
841
- else
842
- cell.content.each do |text|
843
- cell_content = %(\#{cell_content}<p class="tableblock">\#{text}</p>)
844
- end
845
- end
846
- end %><%= (@document.attr? 'cellbgcolor') ? %( style="background-color:\#{@document.attr 'cellbgcolor'};") : nil
847
- %>><%= cell_content %></<%= tsec == :head ? 'th' : 'td' %>><%
848
- end %>
849
- </tr><%
850
- end %>
851
- </t<%= tsec %>><%
852
- end
853
- end %>
854
- </table>
855
- EOS
856
- end
857
- end
858
-
859
- class BlockImageTemplate < BaseTemplate
860
- def image(target, alt, title, link, node)
861
- align = (node.attr? 'align') ? (node.attr 'align') : nil
862
- float = (node.attr? 'float') ? (node.attr 'float') : nil
863
- if align || float
864
- styles = [align ? %(text-align: #{align}) : nil, float ? %(float: #{float}) : nil].compact
865
- style_attribute = %( style="#{styles * ';'}")
866
- else
867
- style_attribute = nil
868
- end
869
-
870
- width_attribute = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : nil
871
- height_attribute = (node.attr? 'height') ? %( height="#{node.attr 'height'}") : nil
872
-
873
- img_element = %(<img src="#{node.image_uri target}" alt="#{alt}"#{width_attribute}#{height_attribute}>)
874
- if link
875
- img_element = %(<a class="image" href="#{link}">#{img_element}</a>)
876
- end
877
- id_attribute = node.id ? %( id="#{node.id}") : nil
878
- classes = ['imageblock', node.style, node.role].compact
879
- class_attribute = %( class="#{classes * ' '}")
880
- title_element = title ? %(\n<div class="title">#{title}</div>) : nil
881
-
882
- %(<div#{id_attribute}#{class_attribute}#{style_attribute}>
883
- <div class="content">
884
- #{img_element}
885
- </div>#{title_element}
886
- </div>)
887
- end
888
-
889
- def result(node)
890
- image(node.attr('target'), node.attr('alt'), node.title? ? node.captioned_title : nil, node.attr('link'), node)
891
- end
892
-
893
- def template
894
- :invoke_result
895
- end
896
- end
897
-
898
- class BlockAudioTemplate < BaseTemplate
899
- def result(node)
900
- id_attribute = node.id ? %( id="#{node.id}") : nil
901
- classes = ['audioblock', node.style, node.role].compact
902
- class_attribute = %( class="#{classes * ' '}")
903
- title_element = node.title? ? %(\n<div class="title">#{node.captioned_title}</div>) : nil
904
- %(<div#{id_attribute}#{class_attribute}>#{title_element}
905
- <div class="content">
906
- <audio src="#{node.media_uri(node.attr 'target')}"#{(node.option? 'autoplay') ? ' autoplay' : nil}#{(node.option? 'nocontrols') ? nil : ' controls'}#{(node.option? 'loop') ? ' loop' : nil}>
907
- Your browser does not support the audio tag.
908
- </audio>
909
- </div>
910
- </div>)
911
- end
912
-
913
- def template
914
- :invoke_result
915
- end
916
- end
917
-
918
- class BlockVideoTemplate < BaseTemplate
919
- def result(node)
920
- id_attribute = node.id ? %( id="#{node.id}") : nil
921
- classes = ['videoblock', node.style, node.role].compact
922
- class_attribute = %( class="#{classes * ' '}")
923
- title_element = node.title? ? %(\n<div class="title">#{node.captioned_title}</div>) : nil
924
- width_attribute = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : nil
925
- height_attribute = (node.attr? 'height') ? %( height="#{node.attr 'height'}") : nil
926
- case node.attr 'poster'
927
- when 'vimeo'
928
- start_anchor = (node.attr? 'start') ? "#at=#{node.attr 'start'}" : nil
929
- delimiter = '?'
930
- autoplay_param = (node.option? 'autoplay') ? "#{delimiter}autoplay=1" : nil
931
- delimiter = '&amp;' if autoplay_param
932
- loop_param = (node.option? 'loop') ? "#{delimiter}loop=1" : nil
933
- %(<div#{id_attribute}#{class_attribute}>#{title_element}
934
- <div class="content">
935
- <iframe#{width_attribute}#{height_attribute} src="//player.vimeo.com/video/#{node.attr 'target'}#{start_anchor}#{autoplay_param}#{loop_param}" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
936
- </div>
937
- </div>)
938
- when 'youtube'
939
- start_param = (node.attr? 'start') ? "&amp;start=#{node.attr 'start'}" : nil
940
- end_param = (node.attr? 'end') ? "&amp;end=#{node.attr 'end'}" : nil
941
- autoplay_param = (node.option? 'autoplay') ? '&amp;autoplay=1' : nil
942
- loop_param = (node.option? 'loop') ? '&amp;loop=1' : nil
943
- controls_param = (node.option? 'nocontrols') ? '&amp;controls=0' : nil
944
- %(<div#{id_attribute}#{class_attribute}>#{title_element}
945
- <div class="content">
946
- <iframe#{width_attribute}#{height_attribute} src="//www.youtube.com/embed/#{node.attr 'target'}?rel=0#{start_param}#{end_param}#{autoplay_param}#{loop_param}#{controls_param}" frameborder="0"#{(node.option? 'nofullscreen') ? nil : ' allowfullscreen'}></iframe>
947
- </div>
948
- </div>)
949
- else
950
- poster_attribute = (node.attr? 'poster') ? %( poster="#{node.media_uri(node.attr 'poster')}") : nil
951
- %(<div#{id_attribute}#{class_attribute}>#{title_element}
952
- <div class="content">
953
- <video src="#{node.media_uri(node.attr 'target')}"#{width_attribute}#{height_attribute}#{poster_attribute}#{(node.option? 'autoplay') ? ' autoplay' : nil}#{(node.option? 'nocontrols') ? nil : ' controls'}#{(node.option? 'loop') ? ' loop' : nil}>
954
- Your browser does not support the video tag.
955
- </video>
956
- </div>
957
- </div>)
958
- end
959
- end
960
-
961
- def template
962
- :invoke_result
963
- end
964
- end
965
-
966
- class BlockRulerTemplate < BaseTemplate
967
- def result(node)
968
- '<hr>'
969
- end
970
-
971
- def template
972
- :invoke_result
973
- end
974
- end
975
-
976
- class BlockPageBreakTemplate < BaseTemplate
977
- def result(node)
978
- %(<div style="page-break-after: always;"></div>)
979
- end
980
-
981
- def template
982
- :invoke_result
983
- end
984
- end
985
-
986
- class InlineBreakTemplate < BaseTemplate
987
- def result(node)
988
- %(#{node.text}<br>\n)
989
- end
990
-
991
- def template
992
- :invoke_result
993
- end
994
- end
995
-
996
- class InlineCalloutTemplate < BaseTemplate
997
- def result(node)
998
- if node.document.attr? 'icons', 'font'
999
- %(<i class="conum" data-value="#{node.text}"></i><b>(#{node.text})</b>)
1000
- elsif node.document.attr? 'icons'
1001
- src = node.icon_uri("callouts/#{node.text}")
1002
- %(<img src="#{src}" alt="#{node.text}">)
1003
- else
1004
- "<b>(#{node.text})</b>"
1005
- end
1006
- end
1007
-
1008
- def template
1009
- :invoke_result
1010
- end
1011
- end
1012
-
1013
- class InlineQuotedTemplate < BaseTemplate
1014
- NO_TAGS = [nil, nil, nil]
1015
-
1016
- QUOTE_TAGS = {
1017
- :emphasis => ['<em>', '</em>', true],
1018
- :strong => ['<strong>', '</strong>', true],
1019
- :monospaced => ['<code>', '</code>', true],
1020
- :superscript => ['<sup>', '</sup>', true],
1021
- :subscript => ['<sub>', '</sub>', true],
1022
- :double => ['&#8220;', '&#8221;', false],
1023
- :single => ['&#8216;', '&#8217;', false]
1024
- }
1025
-
1026
- def quote_text(text, type, id, role)
1027
- open, close, is_tag = QUOTE_TAGS[type] || NO_TAGS
1028
- anchor = id.nil? ? nil : %(<a id="#{id}"></a>)
1029
- if role
1030
- if is_tag
1031
- quoted_text = %(#{open.chop} class="#{role}">#{text}#{close})
1032
- else
1033
- quoted_text = %(<span class="#{role}">#{open}#{text}#{close}</span>)
1034
- end
1035
- elsif open.nil?
1036
- quoted_text = text
1037
- else
1038
- quoted_text = %(#{open}#{text}#{close})
1039
- end
1040
-
1041
- anchor.nil? ? quoted_text : %(#{anchor}#{quoted_text})
1042
- end
1043
-
1044
- def result(node)
1045
- quote_text(node.text, node.type, node.id, node.role)
1046
- end
1047
-
1048
- def template
1049
- :invoke_result
1050
- end
1051
- end
1052
-
1053
- class InlineButtonTemplate < BaseTemplate
1054
- def result(node)
1055
- %(<b class="button">#{node.text}</b>)
1056
- end
1057
-
1058
- def template
1059
- :invoke_result
1060
- end
1061
- end
1062
-
1063
- class InlineKbdTemplate < BaseTemplate
1064
- def result(node)
1065
- keys = node.attr 'keys'
1066
- if keys.size == 1
1067
- %(<kbd>#{keys.first}</kbd>)
1068
- else
1069
- key_combo = keys.map{|key| %(<kbd>#{key}</kbd>+) }.join.chop
1070
- %(<kbd class="keyseq">#{key_combo}</kbd>)
1071
- end
1072
- end
1073
-
1074
- def template
1075
- :invoke_result
1076
- end
1077
- end
1078
-
1079
- class InlineMenuTemplate < BaseTemplate
1080
- def menu(menu, submenus, menuitem)
1081
- if !submenus.empty?
1082
- submenu_path = submenus.map{|submenu| %(<span class="submenu">#{submenu}</span>&#160;&#9656; ) }.join.chop
1083
- %(<span class="menuseq"><span class="menu">#{menu}</span>&#160;&#9656; #{submenu_path} <span class="menuitem">#{menuitem}</span></span>)
1084
- elsif !menuitem.nil?
1085
- %(<span class="menuseq"><span class="menu">#{menu}</span>&#160;&#9656; <span class="menuitem">#{menuitem}</span></span>)
1086
- else
1087
- %(<span class="menu">#{menu}</span>)
1088
- end
1089
- end
1090
-
1091
- def result(node)
1092
- menu(node.attr('menu'), node.attr('submenus'), node.attr('menuitem'))
1093
- end
1094
-
1095
- def template
1096
- :invoke_result
1097
- end
1098
- end
1099
-
1100
- class InlineAnchorTemplate < BaseTemplate
1101
- def anchor(target, text, type, document, node)
1102
- case type
1103
- when :xref
1104
- refid = (node.attr 'refid') || target
1105
- if text.nil?
1106
- # FIXME this seems like it should be prepared already
1107
- text = document.references[:ids].fetch(refid, "[#{refid}]") if text.nil?
1108
- end
1109
- %(<a href="#{target}">#{text}</a>)
1110
- when :ref
1111
- %(<a id="#{target}"></a>)
1112
- when :link
1113
- %(<a href="#{target}"#{node.role? ? " class=\"#{node.role}\"" : nil}#{(node.attr? 'window') ? " target=\"#{node.attr 'window'}\"" : nil}>#{text}</a>)
1114
- when :bibref
1115
- %(<a id="#{target}"></a>[#{target}])
1116
- end
1117
- end
1118
-
1119
- def result(node)
1120
- anchor(node.target, node.text, node.type, node.document, node)
1121
- end
1122
-
1123
- def template
1124
- :invoke_result
1125
- end
1126
- end
1127
-
1128
- class InlineImageTemplate < BaseTemplate
1129
- def image(target, type, node)
1130
- if type == 'icon' && (node.document.attr? 'icons', 'font')
1131
- style_class = "icon-#{target}"
1132
- if node.attr? 'size'
1133
- style_class = "#{style_class} icon-#{node.attr 'size'}"
1134
- end
1135
- if node.attr? 'rotate'
1136
- style_class = "#{style_class} icon-rotate-#{node.attr 'rotate'}"
1137
- end
1138
- if node.attr? 'flip'
1139
- style_class = "#{style_class} icon-flip-#{node.attr 'flip'}"
1140
- end
1141
- title_attribute = (node.attr? 'title') ? %( title="#{node.attr 'title'}") : nil
1142
- img = %(<i class="#{style_class}"#{title_attribute}></i>)
1143
- elsif type == 'icon' && !(node.document.attr? 'icons')
1144
- img = "[#{node.attr 'alt'}]"
1145
- else
1146
- if type == 'icon'
1147
- resolved_target = node.icon_uri target
1148
- else
1149
- resolved_target = node.image_uri target
1150
- end
1151
-
1152
- attrs = ['alt', 'width', 'height', 'title'].map {|name|
1153
- if node.attr? name
1154
- %( #{name}="#{node.attr name}")
1155
- else
1156
- nil
1157
- end
1158
- }.join
1159
-
1160
- img = %(<img src="#{resolved_target}"#{attrs}>)
1161
- end
1162
-
1163
- if node.attr? 'link'
1164
- img = %(<a class="image" href="#{node.attr 'link'}"#{(node.attr? 'window') ? " target=\"#{node.attr 'window'}\"" : nil}>#{img}</a>)
1165
- end
1166
-
1167
- if node.role?
1168
- style_classes = %(#{type} #{node.role})
1169
- else
1170
- style_classes = type
1171
- end
1172
-
1173
- style_attr = (node.attr? 'float') ? %( style="float: #{node.attr 'float'}") : nil
1174
-
1175
- %(<span class="#{style_classes}"#{style_attr}>#{img}</span>)
1176
- end
1177
-
1178
- def result(node)
1179
- image(node.target, node.type, node)
1180
- end
1181
-
1182
- def template
1183
- :invoke_result
1184
- end
1185
- end
1186
-
1187
- class InlineFootnoteTemplate < BaseTemplate
1188
- def result(node)
1189
- index = node.attr :index
1190
- if node.type == :xref
1191
- %(<span class="footnoteref">[<a class="footnote" href="#_footnote_#{index}" title="View footnote.">#{index}</a>]</span>)
1192
- else
1193
- id_attribute = node.id ? %( id="_footnote_#{node.id}") : nil
1194
- %(<span class="footnote"#{id_attribute}>[<a id="_footnoteref_#{index}" class="footnote" href="#_footnote_#{index}" title="View footnote.">#{index}</a>]</span>)
1195
- end
1196
- end
1197
-
1198
- def template
1199
- :invoke_result
1200
- end
1201
- end
1202
-
1203
- class InlineIndextermTemplate < BaseTemplate
1204
- def result(node)
1205
- node.type == :visible ? node.text : ''
1206
- end
1207
-
1208
- def template
1209
- :invoke_result
1210
- end
1211
- end
1212
-
1213
- end # module HTML5
1214
- end # module Asciidoctor