asciidoctor 0.1.3 → 0.1.4

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +387 -0
  3. data/README.adoc +358 -348
  4. data/asciidoctor.gemspec +30 -9
  5. data/bin/asciidoctor +3 -0
  6. data/bin/asciidoctor-safe +3 -0
  7. data/compat/asciidoc.conf +76 -4
  8. data/lib/asciidoctor.rb +174 -79
  9. data/lib/asciidoctor/abstract_block.rb +131 -101
  10. data/lib/asciidoctor/abstract_node.rb +108 -26
  11. data/lib/asciidoctor/attribute_list.rb +1 -1
  12. data/lib/asciidoctor/backends/_stylesheets.rb +204 -62
  13. data/lib/asciidoctor/backends/base_template.rb +11 -22
  14. data/lib/asciidoctor/backends/docbook45.rb +158 -163
  15. data/lib/asciidoctor/backends/docbook5.rb +103 -0
  16. data/lib/asciidoctor/backends/html5.rb +662 -445
  17. data/lib/asciidoctor/block.rb +54 -44
  18. data/lib/asciidoctor/cli/invoker.rb +41 -20
  19. data/lib/asciidoctor/cli/options.rb +66 -20
  20. data/lib/asciidoctor/debug.rb +1 -1
  21. data/lib/asciidoctor/document.rb +265 -100
  22. data/lib/asciidoctor/extensions.rb +443 -0
  23. data/lib/asciidoctor/helpers.rb +38 -6
  24. data/lib/asciidoctor/inline.rb +5 -5
  25. data/lib/asciidoctor/lexer.rb +532 -250
  26. data/lib/asciidoctor/{list_item.rb → list.rb} +33 -13
  27. data/lib/asciidoctor/path_resolver.rb +28 -2
  28. data/lib/asciidoctor/reader.rb +814 -455
  29. data/lib/asciidoctor/renderer.rb +128 -42
  30. data/lib/asciidoctor/section.rb +55 -41
  31. data/lib/asciidoctor/substituters.rb +380 -107
  32. data/lib/asciidoctor/table.rb +40 -30
  33. data/lib/asciidoctor/version.rb +1 -1
  34. data/man/asciidoctor.1 +32 -96
  35. data/man/{asciidoctor.ad → asciidoctor.adoc} +57 -48
  36. data/test/attributes_test.rb +200 -27
  37. data/test/blocks_test.rb +361 -22
  38. data/test/document_test.rb +496 -81
  39. data/test/extensions_test.rb +448 -0
  40. data/test/fixtures/basic-docinfo-footer.html +6 -0
  41. data/test/fixtures/basic-docinfo-footer.xml +8 -0
  42. data/test/fixtures/basic-docinfo.xml +3 -3
  43. data/test/fixtures/basic.asciidoc +1 -0
  44. data/test/fixtures/child-include.adoc +5 -0
  45. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +6 -0
  46. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +1 -0
  47. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +3 -0
  48. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +5 -0
  49. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +6 -0
  50. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +3 -0
  51. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +5 -0
  52. data/test/fixtures/docinfo-footer.html +1 -0
  53. data/test/fixtures/docinfo-footer.xml +9 -0
  54. data/test/fixtures/docinfo.xml +1 -0
  55. data/test/fixtures/grandchild-include.adoc +3 -0
  56. data/test/fixtures/parent-include-restricted.adoc +5 -0
  57. data/test/fixtures/parent-include.adoc +5 -0
  58. data/test/invoker_test.rb +82 -8
  59. data/test/lexer_test.rb +21 -3
  60. data/test/links_test.rb +34 -2
  61. data/test/lists_test.rb +304 -7
  62. data/test/options_test.rb +19 -3
  63. data/test/paragraphs_test.rb +13 -0
  64. data/test/paths_test.rb +22 -0
  65. data/test/preamble_test.rb +20 -0
  66. data/test/reader_test.rb +1096 -644
  67. data/test/renderer_test.rb +152 -12
  68. data/test/sections_test.rb +417 -76
  69. data/test/substitutions_test.rb +339 -138
  70. data/test/tables_test.rb +109 -4
  71. data/test/test_helper.rb +79 -13
  72. data/test/text_test.rb +111 -11
  73. metadata +54 -18
@@ -0,0 +1,103 @@
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,32 +1,11 @@
1
1
  require 'asciidoctor/backends/_stylesheets'
2
2
 
3
3
  module Asciidoctor
4
- class BaseTemplate
5
-
6
- # create template matter to insert a style class from the role attribute if specified
7
- def role_class
8
- attrvalue('role')
9
- end
10
-
11
- # create template matter to insert a style class from the style attribute if specified
12
- def style_class(sibling = true)
13
- attrvalue('style', sibling, false)
14
- end
15
-
16
- def title_div(opts = {})
17
- if opts.has_key? :caption
18
- %q(<% if title? %><div class="title"><%= @caption %><%= title %></div><% end %>)
19
- else
20
- %q(<% if title? %><div class="title"><%= title %></div><% end %>)
21
- end
22
- end
23
- end
24
-
25
4
  module HTML5
26
5
 
27
6
  class DocumentTemplate < BaseTemplate
28
7
  def self.outline(node, to_depth = 2)
29
- toc_level = nil
8
+ toc_level_buffer = []
30
9
  sections = node.sections
31
10
  unless sections.empty?
32
11
  # FIXME the level for special sections should be set correctly in the model
@@ -35,31 +14,25 @@ class DocumentTemplate < BaseTemplate
35
14
  if sec_level == 0 && sections.first.special
36
15
  sec_level = 1
37
16
  end
38
- toc_level = %(<ol type="none" class="sectlevel#{sec_level}">\n)
39
- numbered = node.document.attr? 'numbered'
17
+ toc_level_buffer << %(<ul class="sectlevel#{sec_level}">)
40
18
  sections.each do |section|
41
- # need to check playback attributes for change in numbered setting
42
- # FIXME encapsulate me
43
- if section.attributes.has_key? :attribute_entries
44
- if (numbered_override = section.attributes[:attribute_entries].find {|entry| entry.name == 'numbered'})
45
- numbered = numbered_override.negate ? false : true
46
- end
47
- end
48
- section_num = numbered && !section.special && section.level > 0 && section.level < 4 ? %(#{section.sectnum} ) : nil
49
- toc_level = %(#{toc_level}<li><a href=\"##{section.id}\">#{section_num}#{section.caption}#{section.title}</a></li>\n)
50
- if section.level < to_depth && (child_toc_level = outline(section, to_depth))
51
- toc_level = %(#{toc_level}<li>\n#{child_toc_level}\n</li>\n)
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>'
52
25
  end
53
26
  end
54
- toc_level = %(#{toc_level}</ol>)
27
+ toc_level_buffer << '</ul>'
55
28
  end
56
- toc_level
29
+ toc_level_buffer * EOL
57
30
  end
58
31
 
59
32
  def template
60
33
  @template ||= @eruby.new <<-EOS
61
34
  <%#encoding:UTF-8%><!DOCTYPE html>
62
- <html<%= !(attr? 'nolang') ? %( lang="\#{attr 'lang', 'en'}") : nil %>>
35
+ <html<%= (attr? 'nolang') ? nil : %( lang="\#{attr 'lang', 'en'}") %>>
63
36
  <head>
64
37
  <meta http-equiv="Content-Type" content="text/html; charset=<%= attr :encoding %>">
65
38
  <meta name="generator" content="Asciidoctor <%= attr 'asciidoctor-version' %>">
@@ -70,17 +43,17 @@ end
70
43
  if attr? :keywords %>
71
44
  <meta name="keywords" content="<%= attr :keywords %>"><%
72
45
  end %>
73
- <title><%= doctitle %></title><%
46
+ <title><%= doctitle(:sanitize => true) || (attr 'untitled-label') %></title><%
74
47
  if DEFAULT_STYLESHEET_KEYS.include?(attr 'stylesheet')
75
48
  if @safe >= SafeMode::SECURE || (attr? 'linkcss') %>
76
49
  <link rel="stylesheet" href="<%= normalize_web_path(DEFAULT_STYLESHEET_NAME, (attr :stylesdir, '')) %>"><%
77
50
  else %>
78
51
  <style>
79
- <%= ::Asciidoctor::HTML5.default_asciidoctor_stylesheet %>
52
+ <%= HTML5.default_asciidoctor_stylesheet %>
80
53
  </style><%
81
54
  end
82
55
  elsif attr? :stylesheet
83
- if attr? 'linkcss' %>
56
+ if @safe >= SafeMode::SECURE || (attr? 'linkcss') %>
84
57
  <link rel="stylesheet" href="<%= normalize_web_path((attr :stylesheet), (attr :stylesdir, '')) %>"><%
85
58
  else %>
86
59
  <style>
@@ -90,17 +63,31 @@ elsif attr? :stylesheet
90
63
  end
91
64
  if attr? 'icons', 'font'
92
65
  if !(attr 'iconfont-remote', '').nil? %>
93
- <link rel="stylesheet" href="<%= attr 'iconfont-cdn', 'http://cdnjs.cloudflare.com/ajax/libs/font-awesome/3.1.0/css' %>/<%= attr 'iconfont-name', 'font-awesome' %>.min.css"><%
66
+ <link rel="stylesheet" href="<%= attr 'iconfont-cdn', 'http://cdnjs.cloudflare.com/ajax/libs/font-awesome/3.2.1/css/font-awesome.min.css' %>"><%
94
67
  else %>
95
68
  <link rel="stylesheet" href="<%= normalize_web_path(%(\#{attr 'iconfont-name', 'font-awesome'}.css), (attr 'stylesdir', '')) %>"><%
96
69
  end
97
70
  end
98
71
  case attr 'source-highlighter'
99
72
  when 'coderay'
100
- if (attr 'coderay-css', 'class') == 'class' %>
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 %>
101
87
  <style>
102
- <%= ::Asciidoctor::HTML5.default_coderay_stylesheet %>
88
+ <%= HTML5.pygments_stylesheet(attr 'pygments-style') %>
103
89
  </style><%
90
+ end
104
91
  end
105
92
  when 'highlightjs', 'highlight.js' %>
106
93
  <link rel="stylesheet" href="<%= attr :highlightjsdir, 'http://cdnjs.cloudflare.com/ajax/libs/highlight.js/7.3' %>/styles/<%= attr 'highlightjs-theme', 'default' %>.min.css">
@@ -113,34 +100,55 @@ when 'prettify' %>
113
100
  end %><%= (docinfo_content = docinfo).empty? ? nil : %(
114
101
  \#{docinfo_content}) %>
115
102
  </head>
116
- <body#{id} class="<%= doctype %><%= (attr? 'toc-class') && (attr? 'toc') && (attr? 'toc-placement', 'auto') ? %( \#{attr 'toc-class'}) : nil %>"<%= (attr? 'max-width') ? %( style="max-width: \#{attr 'max-width'};") : nil %>><%
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 %>><%
117
104
  unless noheader %>
118
105
  <div id="header"><%
119
- if has_header?
120
- unless notitle %>
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
121
  <h1><%= @header.title %></h1><%
122
- end %><%
123
- if attr? :author %>
124
- <span id="author"><%= attr :author %></span><br><%
125
- if attr? :email %>
126
- <span id="email"><%= sub_macros(attr :email) %></span><br><%
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
127
135
  end
128
- end
129
- if attr? :revnumber %>
130
- <span id="revnumber">version <%= attr :revnumber %><%= (attr? :revdate) ? ',' : '' %></span><%
131
- end
132
- if attr? :revdate %>
136
+ if attr? :revnumber %>
137
+ <span id="revnumber"><%= ((attr 'version-label') || '').downcase %> <%= attr :revnumber %><%= (attr? :revdate) ? ',' : '' %></span><%
138
+ end
139
+ if attr? :revdate %>
133
140
  <span id="revdate"><%= attr :revdate %></span><%
134
- end
135
- if attr? :revremark %>
141
+ end
142
+ if attr? :revremark %>
136
143
  <br><span id="revremark"><%= attr :revremark %></span><%
144
+ end
137
145
  end
138
- end
139
- if (attr? :toc) && (attr? 'toc-placement', 'auto') %>
146
+ if (attr? :toc) && (attr? 'toc-placement', 'auto') %>
140
147
  <div id="toc" class="<%= attr 'toc-class', 'toc' %>">
141
148
  <div id="toctitle"><%= attr 'toc-title' %></div>
142
149
  <%= template.class.outline(self, (attr :toclevels, 2).to_i) %>
143
150
  </div><%
151
+ end
144
152
  end %>
145
153
  </div><%
146
154
  end %>
@@ -160,10 +168,13 @@ end %>
160
168
  <div id="footer">
161
169
  <div id="footer-text"><%
162
170
  if attr? :revnumber %>
163
- Version <%= attr :revnumber %><br><%
171
+ <%= %(\#{attr 'version-label'} \#{attr :revnumber}) %><br><%
172
+ end
173
+ if attr? 'last-update-label' %>
174
+ <%= %(\#{attr 'last-update-label'} \#{attr :docdatetime}) %><%
164
175
  end %>
165
- Last updated <%= attr :docdatetime %>
166
- </div>
176
+ </div><%= (docinfo_content = docinfo :footer).empty? ? nil : %(
177
+ \#{docinfo_content}) %>
167
178
  </div>
168
179
  </body>
169
180
  </html>
@@ -172,19 +183,32 @@ Last updated <%= attr :docdatetime %>
172
183
  end
173
184
 
174
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
+
175
210
  def template
176
- @template ||= @eruby.new <<-EOS
177
- <%#encoding:UTF-8%><% unless notitle || !has_header? %><h1#{id}><%= header.title %></h1>
178
- <% end %><%= content %>
179
- <% unless !footnotes? || (attr? :nofootnotes) %><div id="footnotes">
180
- <hr>
181
- <% footnotes.each do |fn| %>
182
- <div class="footnote" id="_footnote_<%= fn.index %>">
183
- <a href="#_footnoteref_<%= fn.index %>"><%= fn.index %></a>. <%= fn.text %>
184
- </div>
185
- <% end %>
186
- </div><% end %>
187
- EOS
211
+ :invoke_result
188
212
  end
189
213
  end
190
214
 
@@ -206,7 +230,7 @@ class BlockTocTemplate < BaseTemplate
206
230
  end
207
231
  title = node.title? ? node.title : (doc.attr 'toc-title')
208
232
  levels = (node.attr? 'levels') ? (node.attr 'levels').to_i : (doc.attr 'toclevels', 2).to_i
209
- role = (node.attr? 'role') ? (node.attr 'role') : (doc.attr 'toc-class', 'toc')
233
+ role = node.role? ? node.role : (doc.attr 'toc-class', 'toc')
210
234
 
211
235
  %(<div#{id_attr} class="#{role}">
212
236
  <div#{title_id_attr} class="title">#{title}</div>
@@ -231,14 +255,16 @@ class BlockPreambleTemplate < BaseTemplate
231
255
  end
232
256
  end
233
257
 
234
- def template
235
- @template ||= @eruby.new <<-EOS
236
- <%#encoding:UTF-8%><div id="preamble">
258
+ def result(node)
259
+ %(<div id="preamble">
237
260
  <div class="sectionbody">
238
- <%= content %>
239
- </div><%= template.toc(self) %>
240
- </div>
241
- EOS
261
+ #{node.content}
262
+ </div>#{toc node}
263
+ </div>)
264
+ end
265
+
266
+ def template
267
+ :invoke_result
242
268
  end
243
269
  end
244
270
 
@@ -267,10 +293,10 @@ class SectionTemplate < BaseTemplate
267
293
 
268
294
  if slevel == 0
269
295
  %(<h1#{id} class="sect0">#{anchor}#{link_start}#{sec.title}#{link_end}</h1>
270
- #{sec.content}\n)
296
+ #{sec.content})
271
297
  else
272
- role = (sec.attr? 'role') ? " #{sec.attr 'role'}" : nil
273
- if !sec.special && (sec.document.attr? 'numbered') && slevel < 4
298
+ role = sec.role? ? " #{sec.role}" : nil
299
+ if sec.numbered
274
300
  sectnum = "#{sec.sectnum} "
275
301
  else
276
302
  sectnum = nil
@@ -284,9 +310,9 @@ class SectionTemplate < BaseTemplate
284
310
  content = sec.content
285
311
  end
286
312
  %(<div class="sect#{slevel}#{role}">
287
- <#{htag}#{id}>#{anchor}#{link_start}#{sectnum}#{sec.caption}#{sec.title}#{link_end}</#{htag}>
313
+ <#{htag}#{id}>#{anchor}#{link_start}#{sectnum}#{sec.captioned_title}#{link_end}</#{htag}>
288
314
  #{content}
289
- </div>\n)
315
+ </div>)
290
316
  end
291
317
  end
292
318
 
@@ -296,200 +322,210 @@ class SectionTemplate < BaseTemplate
296
322
  end
297
323
 
298
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
+
299
332
  def template
300
- @template ||= @eruby.new <<-EOS
301
- <%#encoding:UTF-8%><h<%= @level + 1 %>#{id} class="#{style_class false}#{role_class}"><%= title %></h<%= @level + 1 %>>
302
- EOS
333
+ :invoke_result
303
334
  end
304
335
  end
305
336
 
306
337
  class BlockDlistTemplate < BaseTemplate
307
- def template
308
- @template ||= @eruby.new <<-EOS
309
- <%#encoding:UTF-8%><%
310
- continuing = false
311
- entries = content
312
- last_index = entries.length - 1
313
- if attr? 'style', 'qanda', false
314
- %><div#{id} class="qlist#{style_class}#{role_class}"><%
315
- if title? %>
316
- <div class="title"><%= title %></div><%
317
- end %>
318
- <ol><%
319
- entries.each_with_index do |(dt, dd), index|
320
- last = (index == last_index)
321
- unless continuing %>
322
- <li><%
323
- end %>
324
- <p><em><%= dt.text %></em></p><%
325
- if !last && dd.nil?
326
- continuing = true
327
- next
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
328
347
  else
329
- continuing = false
348
+ classes = ['dlist', node.style, node.role].compact
330
349
  end
331
- unless dd.nil?
332
- if dd.text? %>
333
- <p><%= dd.text %></p><%
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>'
334
368
  end
335
- if dd.blocks? %>
336
- <%= dd.content %><%
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>'
337
379
  end
338
- end %>
339
- </li><%
340
- end %>
341
- </ol>
342
- </div><%
343
- elsif attr? 'style', 'horizontal', false
344
- %><div#{id} class="hdlist#{role_class}"><%
345
- if title? %>
346
- <div class="title"><%= title %></div><%
347
- end %>
348
- <table><%
349
- if (attr? :labelwidth) || (attr? :itemwidth) %>
350
- <colgroup>
351
- <col<% if attr? :labelwidth %> style="width:<%= (attr :labelwidth).chomp('%') %>%;"<% end %>>
352
- <col<% if attr? :itemwidth %> style="width:<%= (attr :itemwidth).chomp('%') %>%;"<% end %>>
353
- </colgroup><%
354
- end %><%
355
- entries.each_with_index do |(dt, dd), index|
356
- last = (index == last_index)
357
- unless continuing %>
358
- <tr>
359
- <td class="hdlist1<%= (attr? 'strong-option') ? 'strong' : nil %>"><%
360
- end %>
361
- <%= dt.text %>
362
- <br><%
363
- if !last && dd.nil?
364
- continuing = true
365
- next
366
- else
367
- continuing = false
368
- end %>
369
- </td>
370
- <td class="hdlist2"><%
371
- unless dd.nil?
372
- if dd.text? %>
373
- <p><%= dd.text %></p><%
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>'
374
397
  end
375
- if dd.blocks? %>
376
- <%= dd.content %><%
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
377
412
  end
378
- end %>
379
- </td>
380
- </tr><%
381
- end %>
382
- </table>
383
- </div><%
384
- else
385
- %><div#{id} class="dlist#{style_class}#{role_class}"><%
386
- if title? %>
387
- <div class="title"><%= title %></div><%
388
- end %>
389
- <dl><%
390
- entries.each_with_index do |(dt, dd), index|
391
- last = (index == last_index) %>
392
- <dt<%= !(attr? 'style', nil, false) ? %( class="hdlist1") : nil %>><%= dt.text %></dt><%
393
- unless dd.nil? %>
394
- <dd><%
395
- if dd.text? %>
396
- <p><%= dd.text %></p><%
397
- end %><%
398
- if dd.blocks? %>
399
- <%= dd.content %><%
400
- end %>
401
- </dd><%
413
+ result_buffer << '</dl>'
402
414
  end
403
- end %>
404
- </dl>
405
- </div><%
406
- end %>
407
- EOS
415
+
416
+ result_buffer << '</div>'
417
+ result_buffer * EOL
418
+ end
419
+
420
+ def template
421
+ :invoke_result
408
422
  end
409
423
  end
410
424
 
411
425
  class BlockListingTemplate < BaseTemplate
412
- def template
413
- @template ||= @eruby.new <<-EOS
414
- <%#encoding:UTF-8%><div#{id} class="listingblock#{role_class}">
415
- #{title_div :caption => true}
416
- <div class="content monospaced"><%
417
- if attr? 'style', 'source', false
418
- language = (language = (attr 'language')) ? %(\#{language} language-\#{language}) : nil
419
- case attr 'source-highlighter'
420
- when 'coderay'
421
- pre_class = ' class="CodeRay"'
422
- code_class = language ? %( class="\#{language}") : nil
423
- when 'highlightjs', 'highlight.js'
424
- pre_class = ' class="highlight"'
425
- code_class = language ? %( class="\#{language}") : nil
426
- when 'prettify'
427
- pre_class = %( class="prettyprint\#{(attr? 'linenums') ? ' linenums' : nil})
428
- pre_class = language ? %(\#{pre_class} \#{language}") : %(\#{pre_class}")
429
- code_class = nil
430
- else
431
- pre_class = ' class="highlight"'
432
- code_class = language ? %( class="\#{language}") : nil
433
- end %>
434
- <pre<%= pre_class %>><code<%= code_class %>><%= template.preserve_endlines(content, self) %></code></pre><%
435
- else %>
436
- <pre><%= template.preserve_endlines(content, self) %></pre><%
437
- end %>
438
- </div>
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}
439
461
  </div>
440
- EOS
462
+ </div>)
463
+ end
464
+
465
+ def template
466
+ :invoke_result
441
467
  end
442
468
  end
443
469
 
444
470
  class BlockLiteralTemplate < BaseTemplate
445
- def template
446
- @template ||= @eruby.new <<-EOS
447
- <%#encoding:UTF-8%><div#{id} class="literalblock#{role_class}">
448
- #{title_div}
449
- <div class="content monospaced">
450
- <pre><%= template.preserve_endlines(content, self) %></pre>
451
- </div>
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>
452
477
  </div>
453
- EOS
478
+ </div>)
479
+ end
480
+
481
+ def template
482
+ :invoke_result
454
483
  end
455
484
  end
456
485
 
457
486
  class BlockAdmonitionTemplate < BaseTemplate
458
- def template
459
- @template ||= @eruby.new <<-EOS
460
- <%#encoding:UTF-8%><div#{id} class="admonitionblock <%= attr :name %>#{role_class}">
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}"}">
461
502
  <table>
462
503
  <tr>
463
- <td class="icon"><%
464
- if attr? 'icons', 'font' %>
465
- <i class="icon-<%= attr :name %>" title="<%= @caption %>"></i><%
466
- elsif attr? 'icons' %>
467
- <img src="<%= icon_uri(attr :name) %>" alt="<%= @caption %>"><%
468
- else %>
469
- <div class="title"><%= @caption %></div><%
470
- end %>
504
+ <td class="icon">
505
+ #{caption}
471
506
  </td>
472
- <td class="content">
473
- #{title_div}
474
- <%= content %>
507
+ <td class="content">#{title ? "
508
+ <div class=\"title\">#{title}</div>" : nil}
509
+ #{node.content}
475
510
  </td>
476
511
  </tr>
477
512
  </table>
478
- </div>
479
- EOS
513
+ </div>)
480
514
  end
481
- end
482
515
 
483
- class BlockParagraphTemplate < BaseTemplate
484
- def paragraph(id, role, title, content)
485
- %(<div#{id && " id=\"#{id}\""} class="paragraph#{role && " #{role}"}">#{title && "
486
- <div class=\"title\">#{title}</div>"}
487
- <p>#{content}</p>
488
- </div>\n)
516
+ def template
517
+ :invoke_result
489
518
  end
519
+ end
490
520
 
521
+ class BlockParagraphTemplate < BaseTemplate
491
522
  def result(node)
492
- paragraph(node.id, (node.attr 'role'), (node.title? ? node.title : nil), node.content)
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>)
493
529
  end
494
530
 
495
531
  def template
@@ -498,40 +534,48 @@ class BlockParagraphTemplate < BaseTemplate
498
534
  end
499
535
 
500
536
  class BlockSidebarTemplate < BaseTemplate
501
- def template
502
- @template ||= @eruby.new <<-EOS
503
- <%#encoding:UTF-8%><div#{id} class="sidebarblock#{role_class}">
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] * ' '}">
504
542
  <div class="content">
505
- #{title_div}
506
- <%= content %>
507
- </div>
543
+ #{title_element}#{node.content}
508
544
  </div>
509
- EOS
545
+ </div>)
546
+ end
547
+
548
+ def template
549
+ :invoke_result
510
550
  end
511
551
  end
512
552
 
513
553
  class BlockExampleTemplate < BaseTemplate
514
- def template
515
- @template ||= @eruby.new <<-EOS
516
- <%#encoding:UTF-8%><div#{id} class="exampleblock#{role_class}">
517
- #{title_div :caption => true}
518
- <div class="content">
519
- <%= content %>
520
- </div>
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}
521
561
  </div>
522
- EOS
562
+ </div>)
563
+ end
564
+
565
+ def template
566
+ :invoke_result
523
567
  end
524
568
  end
525
569
 
526
570
  class BlockOpenTemplate < BaseTemplate
527
571
  def result(node)
528
- open_block(node, node.id, (node.attr 'style', nil, false), (node.attr 'role'), node.title? ? node.title : nil, node.content)
572
+ open_block(node, node.id, node.style, node.role, node.title? ? node.title : nil, node.content)
529
573
  end
530
574
 
531
575
  def open_block(node, id, style, role, title, content)
532
576
  if style == 'abstract'
533
- if node.parent == node.document && node.document.attr?('doctype', 'book')
534
- puts 'asciidoctor: WARNING: abstract block cannot be used in a document without a title when doctype is book. Excluding block content.'
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.'
535
579
  ''
536
580
  else
537
581
  %(<div#{id && " id=\"#{id}\""} class="quoteblock abstract#{role && " #{role}"}">#{title &&
@@ -539,10 +583,10 @@ class BlockOpenTemplate < BaseTemplate
539
583
  <blockquote>
540
584
  #{content}
541
585
  </blockquote>
542
- </div>\n)
586
+ </div>)
543
587
  end
544
- elsif style == 'partintro' && (!node.document.attr?('doctype', 'book') || !node.parent.is_a?(Asciidoctor::Section) || node.level != 0)
545
- puts 'asciidoctor: ERROR: partintro block can only be used when doctype is book and it\'s a child of a book part. Excluding block content.'
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.'
546
590
  ''
547
591
  else
548
592
  %(<div#{id && " id=\"#{id}\""} class="openblock#{style != 'open' ? " #{style}" : ''}#{role && " #{role}"}">#{title &&
@@ -550,7 +594,7 @@ class BlockOpenTemplate < BaseTemplate
550
594
  <div class="content">
551
595
  #{content}
552
596
  </div>
553
- </div>\n)
597
+ </div>)
554
598
  end
555
599
  end
556
600
 
@@ -566,139 +610,204 @@ class BlockPassTemplate < BaseTemplate
566
610
  end
567
611
 
568
612
  class BlockQuoteTemplate < BaseTemplate
569
- def template
570
- @template ||= @eruby.new <<-EOS
571
- <%#encoding:UTF-8%><div#{id} class="quoteblock#{role_class}">
572
- #{title_div}
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}
573
629
  <blockquote>
574
- <%= content %>
575
- </blockquote><%
576
- if (attr? :attribution) || (attr? :citetitle) %>
577
- <div class="attribution"><%
578
- if attr? :citetitle %>
579
- <cite><%= attr :citetitle %></cite><%
580
- end
581
- if attr? :attribution
582
- if attr? :citetitle %>
583
- <br><%
584
- end %>
585
- <%= "&#8212; \#{attr :attribution}" %><%
586
- end %>
587
- </div><%
588
- end %>
589
- </div>
590
- EOS
630
+ #{node.content}
631
+ </blockquote>#{attribution_element}
632
+ </div>)
633
+ end
634
+
635
+ def template
636
+ :invoke_result
591
637
  end
592
638
  end
593
639
 
594
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
+
595
661
  def template
596
- @template ||= @eruby.new <<-EOS
597
- <%#encoding:UTF-8%><div#{id} class="verseblock#{role_class}">
598
- #{title_div}
599
- <pre class="content"><%= template.preserve_endlines(content, self) %></pre><%
600
- if (attr? :attribution) || (attr? :citetitle) %>
601
- <div class="attribution"><%
602
- if attr? :citetitle %>
603
- <cite><%= attr :citetitle %></cite><%
604
- end
605
- if attr? :attribution
606
- if attr? :citetitle %>
607
- <br><%
608
- end %>
609
- <%= "&#8212; \#{attr :attribution}" %><%
610
- end %>
611
- </div><%
612
- end %>
613
- </div>
614
- EOS
662
+ :invoke_result
615
663
  end
616
664
  end
617
665
 
618
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
+
619
717
  def template
620
- @template ||= @eruby.new <<-EOS
621
- <%#encoding:UTF-8%><div#{id} class="ulist#{style_class}#{role_class}">
622
- #{title_div}
623
- <ul><%
624
- content.each do |item| %>
625
- <li>
626
- <p><%= item.text %></p><%
627
- if item.blocks? %>
628
- <%= item.content %><%
629
- end %>
630
- </li><%
631
- end %>
632
- </ul>
633
- </div>
634
- EOS
718
+ :invoke_result
635
719
  end
636
720
  end
637
721
 
638
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
639
748
 
640
749
  def template
641
- @template ||= @eruby.new <<-EOS
642
- <%#encoding:UTF-8%><% style = attr 'style', nil, false %><div#{id} class="olist#{style_class}#{role_class}">
643
- #{title_div}
644
- <ol class="<%= style %>"<%= (type = ::Asciidoctor::ORDERED_LIST_KEYWORDS[style]) ? %( type="\#{type}") : nil %>#{attribute('start', :start)}><%
645
- content.each do |item| %>
646
- <li>
647
- <p><%= item.text %></p><%
648
- if item.blocks? %>
649
- <%= item.content %><%
650
- end %>
651
- </li><%
652
- end %>
653
- </ol>
654
- </div>
655
- EOS
750
+ :invoke_result
656
751
  end
657
752
  end
658
753
 
659
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
+
660
794
  def template
661
- @template ||= @eruby.new <<-EOS
662
- <%#encoding:UTF-8%><div#{id} class="colist#{style_class}#{role_class}">
663
- #{title_div}<%
664
- if attr? :icons %>
665
- <table><%
666
- content.each_with_index do |item, i| %>
667
- <tr>
668
- <td><%
669
- if attr? :icons, 'font' %><i class="conum"><%= i + 1 %></i><%
670
- else %><img src="<%= icon_uri("callouts/\#{i + 1}") %>" alt="<%= i + 1 %>"><%
671
- end %></td>
672
- <td><%= item.text %></td>
673
- </tr><%
674
- end %>
675
- </table><%
676
- else %>
677
- <ol><%
678
- content.each do |item| %>
679
- <li>
680
- <p><%= item.text %></p>
681
- </li><%
682
- end %>
683
- </ol><%
684
- end %>
685
- </div>
686
- EOS
795
+ :invoke_result
687
796
  end
688
797
  end
689
798
 
690
799
  class BlockTableTemplate < BaseTemplate
691
800
  def template
692
801
  @template ||= @eruby.new <<-EOS
693
- <%#encoding:UTF-8%><table#{id} class="tableblock frame-<%= attr :frame, 'all' %> grid-<%= attr :grid, 'all'%>#{role_class}" style="<%
694
- if !(attr? 'autowidth-option') %>width:<%= attr :tablepcwidth %>%; <% end %><%
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 %><%
695
804
  if attr? :float %>float: <%= attr :float %>; <% end %>"><%
696
805
  if title? %>
697
- <caption class="title"><% unless @caption.nil? %><%= @caption %><% end %><%= title %></caption><%
806
+ <caption class="title"><%= captioned_title %></caption><%
698
807
  end
699
808
  if (attr :rowcount) >= 0 %>
700
809
  <colgroup><%
701
- if attr? 'autowidth-option'
810
+ if option? 'autowidth'
702
811
  @columns.each do %>
703
812
  <col><%
704
813
  end
@@ -718,13 +827,13 @@ if (attr :rowcount) >= 0 %>
718
827
  if tsec == :head
719
828
  cell_content = cell.text
720
829
  else
721
- case (cell.attr 'style', nil, false)
830
+ case cell.style
722
831
  when :asciidoc
723
832
  cell_content = %(<div>\#{cell.content}</div>)
724
833
  when :verse
725
834
  cell_content = %(<div class="verse">\#{template.preserve_endlines(cell.text, self)}</div>)
726
835
  when :literal
727
- cell_content = %(<div class="literal monospaced"><pre>\#{template.preserve_endlines(cell.text, self)}</pre></div>)
836
+ cell_content = %(<div class="literal"><pre>\#{template.preserve_endlines(cell.text, self)}</pre></div>)
728
837
  when :header
729
838
  cell.content.each do |text|
730
839
  cell_content = %(\#{cell_content}<p class="tableblock header">\#{text}</p>)
@@ -748,59 +857,109 @@ end %>
748
857
  end
749
858
 
750
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
+
751
893
  def template
752
- @template ||= @eruby.new <<-EOS
753
- <%#encoding:UTF-8%><div#{id} class="imageblock#{style_class}#{role_class}"<%
754
- if (attr? :align) || (attr? :float) %> style="<%
755
- if attr? :align %>text-align: <%= attr :align %><% if attr? :float %>; <% end %><% end %><% if attr? :float %>float: <%= attr :float %><% end %>"<%
756
- end %>>
757
- <div class="content"><%
758
- if attr? :link %>
759
- <a class="image" href="<%= attr :link %>"><img src="<%= image_uri(attr :target) %>" alt="<%= attr :alt %>"#{attribute('width', :width)}#{attribute('height', :height)}></a><%
760
- else %>
761
- <img src="<%= image_uri(attr :target) %>" alt="<%= attr :alt %>"#{attribute('width', :width)}#{attribute('height', :height)}><%
762
- end %>
763
- </div>
764
- #{title_div :caption => true}
765
- </div>
766
- EOS
894
+ :invoke_result
767
895
  end
768
896
  end
769
897
 
770
898
  class BlockAudioTemplate < BaseTemplate
771
- def template
772
- @template ||= @eruby.new <<-EOS
773
- <%#encoding:UTF-8%><div#{id} class="audioblock#{style_class}#{role_class}">
774
- #{title_div :caption => true}
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}
775
905
  <div class="content">
776
- <audio src="<%= media_uri(attr :target) %>"<%
777
- if attr? 'autoplay-option' %> autoplay<% end %><%
778
- unless attr? 'nocontrols-option' %> controls<% end %><%
779
- if attr? 'loop-option' %> loop<% end %>>
906
+ <audio src="#{node.media_uri(node.attr 'target')}"#{(node.option? 'autoplay') ? ' autoplay' : nil}#{(node.option? 'nocontrols') ? nil : ' controls'}#{(node.option? 'loop') ? ' loop' : nil}>
780
907
  Your browser does not support the audio tag.
781
908
  </audio>
782
909
  </div>
783
- </div>
784
- EOS
910
+ </div>)
911
+ end
912
+
913
+ def template
914
+ :invoke_result
785
915
  end
786
916
  end
787
917
 
788
918
  class BlockVideoTemplate < BaseTemplate
789
- def template
790
- @template ||= @eruby.new <<-EOS
791
- <%#encoding:UTF-8%><div#{id} class="videoblock#{style_class}#{role_class}">
792
- #{title_div :caption => true}
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}
793
952
  <div class="content">
794
- <video src="<%= media_uri(attr :target) %>"#{attribute('width', :width)}#{attribute('height', :height)}<%
795
- if attr? 'poster' %> poster="<%= media_uri(attr :poster) %>"<% end %><%
796
- if attr? 'autoplay-option' %> autoplay<% end %><%
797
- unless attr? 'nocontrols-option' %> controls<% end %><%
798
- if attr? 'loop-option' %> loop<% end %>>
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}>
799
954
  Your browser does not support the video tag.
800
955
  </video>
801
956
  </div>
802
- </div>
803
- EOS
957
+ </div>)
958
+ end
959
+ end
960
+
961
+ def template
962
+ :invoke_result
804
963
  end
805
964
  end
806
965
 
@@ -816,7 +975,7 @@ end
816
975
 
817
976
  class BlockPageBreakTemplate < BaseTemplate
818
977
  def result(node)
819
- %(<div style="page-break-after: always;"></div>\n)
978
+ %(<div style="page-break-after: always;"></div>)
820
979
  end
821
980
 
822
981
  def template
@@ -836,13 +995,13 @@ end
836
995
 
837
996
  class InlineCalloutTemplate < BaseTemplate
838
997
  def result(node)
839
- if node.attr? 'icons', 'font'
840
- %(<i class="conum">#{node.text}</i>)
841
- elsif node.attr? 'icons'
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'
842
1001
  src = node.icon_uri("callouts/#{node.text}")
843
1002
  %(<img src="#{src}" alt="#{node.text}">)
844
1003
  else
845
- "<b>&lt;#{node.text}&gt;</b>"
1004
+ "<b>(#{node.text})</b>"
846
1005
  end
847
1006
  end
848
1007
 
@@ -852,33 +1011,38 @@ class InlineCalloutTemplate < BaseTemplate
852
1011
  end
853
1012
 
854
1013
  class InlineQuotedTemplate < BaseTemplate
855
- NO_TAGS = ['', '']
1014
+ NO_TAGS = [nil, nil, nil]
856
1015
 
857
1016
  QUOTE_TAGS = {
858
- :emphasis => ['<em>', '</em>'],
859
- :strong => ['<strong>', '</strong>'],
860
- :monospaced => ['<code>', '</code>'],
861
- :superscript => ['<sup>', '</sup>'],
862
- :subscript => ['<sub>', '</sub>'],
863
- :double => ['&#8220;', '&#8221;'],
864
- :single => ['&#8216;', '&#8217;']
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]
865
1024
  }
866
1025
 
867
- def quote_text(text, type, role)
868
- start_tag, end_tag = QUOTE_TAGS[type] || NO_TAGS
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>)
869
1029
  if role
870
- if start_tag.start_with? '<'
871
- %(#{start_tag.chop} class="#{role}">#{text}#{end_tag})
1030
+ if is_tag
1031
+ quoted_text = %(#{open.chop} class="#{role}">#{text}#{close})
872
1032
  else
873
- %(#{start_tag}<span class="#{role}">#{text}</span>#{end_tag})
1033
+ quoted_text = %(<span class="#{role}">#{open}#{text}#{close}</span>)
874
1034
  end
1035
+ elsif open.nil?
1036
+ quoted_text = text
875
1037
  else
876
- "#{start_tag}#{text}#{end_tag}"
1038
+ quoted_text = %(#{open}#{text}#{close})
877
1039
  end
1040
+
1041
+ anchor.nil? ? quoted_text : %(#{anchor}#{quoted_text})
878
1042
  end
879
1043
 
880
1044
  def result(node)
881
- quote_text(node.text, node.type, (node.attr 'role'))
1045
+ quote_text(node.text, node.type, node.id, node.role)
882
1046
  end
883
1047
 
884
1048
  def template
@@ -937,12 +1101,16 @@ class InlineAnchorTemplate < BaseTemplate
937
1101
  def anchor(target, text, type, document, node)
938
1102
  case type
939
1103
  when :xref
940
- text = document.references[:ids].fetch(target, "[#{target}]") if text.nil?
941
- %(<a href="##{target}">#{text}</a>)
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>)
942
1110
  when :ref
943
1111
  %(<a id="#{target}"></a>)
944
1112
  when :link
945
- %(<a href="#{target}"#{(node.attr? 'role') ? " class=\"#{node.attr 'role'}\"" : nil}#{(node.attr? 'window') ? " target=\"#{node.attr 'window'}\"" : nil}>#{text}</a>)
1113
+ %(<a href="#{target}"#{node.role? ? " class=\"#{node.role}\"" : nil}#{(node.attr? 'window') ? " target=\"#{node.attr 'window'}\"" : nil}>#{text}</a>)
946
1114
  when :bibref
947
1115
  %(<a id="#{target}"></a>[#{target}])
948
1116
  end
@@ -958,28 +1126,77 @@ class InlineAnchorTemplate < BaseTemplate
958
1126
  end
959
1127
 
960
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
+
961
1182
  def template
962
- # care is taken here to avoid a space inside the optional <a> tag
963
- @template ||= @eruby.new <<-EOS
964
- <%#encoding:UTF-8%><span class="image#{role_class}"><%
965
- if attr? :link %><a class="image" href="<%= attr :link %>"><%
966
- end %><img src="<%= image_uri(@target) %>" alt="<%= attr :alt %>"#{attribute('width', :width)}#{attribute('height', :height)}#{attribute('title', :title)}><%
967
- if attr? :link%></a><% end
968
- %></span>
969
- EOS
1183
+ :invoke_result
970
1184
  end
971
1185
  end
972
1186
 
973
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
+
974
1198
  def template
975
- @template ||= @eruby.new <<-EOS
976
- <%#encoding:UTF-8%><%
977
- if @type == :xref
978
- %><span class="footnoteref">[<a class="footnote" href="#_footnote_<%= attr :index %>" title="View footnote."><%= attr :index %></a>]</span><%
979
- else
980
- %><span class="footnote"<% if @id %> id="_footnote_<%= @id %>"<% end %>>[<a id="_footnoteref_<%= attr :index %>" class="footnote" href="#_footnote_<%= attr :index %>" title="View footnote."><%= attr :index %></a>]</span><%
981
- end %>
982
- EOS
1199
+ :invoke_result
983
1200
  end
984
1201
  end
985
1202