asciidoctor 0.1.2 → 0.1.3

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +10 -0
  3. data/Guardfile +18 -0
  4. data/LICENSE +1 -1
  5. data/README.adoc +65 -21
  6. data/Rakefile +10 -0
  7. data/asciidoctor.gemspec +17 -35
  8. data/compat/asciidoc.conf +130 -13
  9. data/lib/asciidoctor.rb +107 -87
  10. data/lib/asciidoctor/abstract_block.rb +6 -2
  11. data/lib/asciidoctor/abstract_node.rb +21 -13
  12. data/lib/asciidoctor/attribute_list.rb +2 -5
  13. data/{stylesheets/asciidoctor.css → lib/asciidoctor/backends/_stylesheets.rb} +96 -46
  14. data/lib/asciidoctor/backends/base_template.rb +9 -4
  15. data/lib/asciidoctor/backends/docbook45.rb +246 -138
  16. data/lib/asciidoctor/backends/html5.rb +580 -381
  17. data/lib/asciidoctor/block.rb +2 -50
  18. data/lib/asciidoctor/cli/options.rb +9 -8
  19. data/lib/asciidoctor/document.rb +35 -45
  20. data/lib/asciidoctor/helpers.rb +10 -0
  21. data/lib/asciidoctor/lexer.rb +456 -148
  22. data/lib/asciidoctor/list_item.rb +0 -21
  23. data/lib/asciidoctor/path_resolver.rb +18 -12
  24. data/lib/asciidoctor/reader.rb +71 -26
  25. data/lib/asciidoctor/renderer.rb +2 -19
  26. data/lib/asciidoctor/section.rb +0 -1
  27. data/lib/asciidoctor/substituters.rb +150 -36
  28. data/lib/asciidoctor/table.rb +30 -24
  29. data/lib/asciidoctor/version.rb +1 -1
  30. data/man/asciidoctor.1 +22 -16
  31. data/man/asciidoctor.ad +24 -16
  32. data/test/attributes_test.rb +50 -0
  33. data/test/blocks_test.rb +660 -9
  34. data/test/document_test.rb +191 -14
  35. data/test/fixtures/encoding.asciidoc +8 -0
  36. data/test/invoker_test.rb +47 -0
  37. data/test/lexer_test.rb +172 -0
  38. data/test/links_test.rb +28 -0
  39. data/test/lists_test.rb +172 -13
  40. data/test/options_test.rb +29 -2
  41. data/test/paragraphs_test.rb +105 -47
  42. data/test/paths_test.rb +3 -3
  43. data/test/reader_test.rb +46 -0
  44. data/test/sections_test.rb +365 -12
  45. data/test/substitutions_test.rb +127 -11
  46. data/test/tables_test.rb +81 -14
  47. data/test/test_helper.rb +18 -7
  48. data/test/text_test.rb +17 -5
  49. metadata +9 -36
@@ -1,147 +1,171 @@
1
+ require 'asciidoctor/backends/_stylesheets'
2
+
1
3
  module Asciidoctor
2
4
  class BaseTemplate
3
5
 
4
6
  # create template matter to insert a style class from the role attribute if specified
5
7
  def role_class
6
- attrvalue(:role)
8
+ attrvalue('role')
7
9
  end
8
10
 
9
11
  # create template matter to insert a style class from the style attribute if specified
10
12
  def style_class(sibling = true)
11
- attrvalue(:style, sibling)
13
+ attrvalue('style', sibling, false)
12
14
  end
13
15
 
14
16
  def title_div(opts = {})
15
- %(<% if title? %><div class="title">#{opts.has_key?(:caption) ? '<%= @caption %>' : ''}<%= title %></div><% end %>)
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
16
22
  end
17
23
  end
18
24
 
19
25
  module HTML5
26
+
20
27
  class DocumentTemplate < BaseTemplate
21
28
  def self.outline(node, to_depth = 2)
22
29
  toc_level = nil
23
30
  sections = node.sections
24
31
  unless sections.empty?
25
- toc_level, indent = ''
26
- nested = true
27
- unless node.is_a?(Document)
28
- if node.document.doctype == 'book'
29
- indent = ' ' * node.level unless node.level == 0
30
- nested = node.level > 0
31
- else
32
- indent = ' ' * node.level
33
- end
32
+ # FIXME the level for special sections should be set correctly in the model
33
+ # sec_level will only be 0 if we have a book doctype with parts
34
+ sec_level = sections.first.level
35
+ if sec_level == 0 && sections.first.special
36
+ sec_level = 1
34
37
  end
35
- toc_level << "#{indent}<ol>\n" if nested
38
+ toc_level = %(<ol type="none" class="sectlevel#{sec_level}">\n)
39
+ numbered = node.document.attr? 'numbered'
36
40
  sections.each do |section|
37
- toc_level << "#{indent} <li><a href=\"##{section.id}\">#{!section.special && section.level > 0 ? "#{section.sectnum} " : ''}#{section.attr('caption')}#{section.title}</a></li>\n"
38
- if section.level < to_depth && (child_toc_level = outline(section, to_depth))
39
- if section.document.doctype != 'book' || section.level > 0
40
- toc_level << "#{indent} <li>\n#{child_toc_level}\n#{indent} </li>\n"
41
- else
42
- toc_level << "#{indent}#{child_toc_level}\n"
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
43
46
  end
44
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)
52
+ end
45
53
  end
46
- toc_level << "#{indent}</ol>" if nested
54
+ toc_level = %(#{toc_level}</ol>)
47
55
  end
48
56
  toc_level
49
57
  end
50
58
 
51
- # Internal: Generate the default stylesheet for CodeRay
52
- #
53
- # returns the default CodeRay stylesheet as a String
54
- def self.default_coderay_stylesheet
55
- Helpers.require_library 'coderay'
56
- ::CodeRay::Encoders[:html]::CSS.new(:default).stylesheet
57
- end
58
-
59
59
  def template
60
60
  @template ||= @eruby.new <<-EOS
61
61
  <%#encoding:UTF-8%><!DOCTYPE html>
62
- <html<% unless attr? :nolang %> lang="<%= attr :lang, 'en' %>"<% end %>>
63
- <head>
64
- <meta http-equiv="Content-Type" content="text/html; charset=<%= attr :encoding %>">
65
- <meta name="generator" content="Asciidoctor <%= attr 'asciidoctor-version' %>">
66
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
67
- <% if attr? :description %>
68
- <meta name="description" content="<%= attr :description %>">
69
- <% end %>
70
- <% if attr? :keywords %>
71
- <meta name="keywords" content="<%= attr :keywords %>">
72
- <% end %>
73
- <title><%= doctitle %></title>
74
- <% if DEFAULT_STYLESHEET_KEYS.include?(attr 'stylesheet') %>
75
- <% if @safe >= SafeMode::SECURE || (attr? 'linkcss') %>
76
- <link rel="stylesheet" href="<%= normalize_web_path(DEFAULT_STYLESHEET_NAME, (attr :stylesdir, '')) %>">
77
- <% else %>
78
- <style>
79
- <%= read_asset DEFAULT_STYLESHEET_PATH %>
80
- </style>
81
- <% end %>
82
- <% elsif attr? :stylesheet %>
83
- <% if attr? 'linkcss' %>
84
- <link rel="stylesheet" href="<%= normalize_web_path((attr :stylesheet), attr(:stylesdir, '')) %>">
85
- <% else %>
86
- <style>
87
- <%= read_asset normalize_system_path(attr(:stylesheet), attr(:stylesdir, '')), true %>
88
- </style>
89
- <% end %>
90
- <% end %>
91
- <% case attr 'source-highlighter' %><%
92
- when 'coderay' %>
93
- <% if (attr 'coderay-css', 'class') == 'class' %>
94
- <style>
95
- <%= template.class.default_coderay_stylesheet %>
96
- </style>
97
- <% end %><%
98
- when 'highlightjs' %>
99
- <link rel="stylesheet" href="<%= (attr :highlightjsdir, 'http://cdnjs.cloudflare.com/ajax/libs/highlight.js/7.3') %>/styles/<%= (attr 'highlightjs-theme', 'default') %>.min.css">
100
- <script src="<%= (attr :highlightjsdir, 'http://cdnjs.cloudflare.com/ajax/libs/highlight.js/7.3') %>/highlight.min.js"></script>
101
- <script>hljs.initHighlightingOnLoad()</script>
102
- <% end %>
103
- <%= docinfo %>
104
- </head>
105
- <body#{id} class="<%= doctype %>"<% if attr? 'max-width' %> style="max-width: <%= attr 'max-width' %>;"<% end %>>
106
- <% unless noheader %>
107
- <div id="header">
108
- <% if has_header? %>
109
- <% unless notitle %>
110
- <h1><%= @header.title %></h1>
111
- <% end %>
112
- <% if attr? :author %><span id="author"><%= attr :author %></span><br>
113
- <% if attr? :email %><span id="email"><%= sub_macros(attr :email) %></span><br><% end %><% end %>
114
- <% if attr? :revnumber %><span id="revnumber">version <%= attr :revnumber %><%= attr?(:revdate) ? ',' : '' %></span><% end %>
115
- <% if attr? :revdate %><span id="revdate"><%= attr :revdate %></span><% end %>
116
- <% if attr? :revremark %><br><span id="revremark"><%= attr :revremark %></span><% end %>
117
- <% end %>
118
- <% if (attr? :toc) && (attr? 'toc-placement', 'auto') %>
119
- <div id="toc" class="<%= attr 'toc-class', 'toc' %>">
120
- <div id="toctitle"><%= attr 'toc-title' %></div>
62
+ <html<%= !(attr? 'nolang') ? %( lang="\#{attr 'lang', 'en'}") : nil %>>
63
+ <head>
64
+ <meta http-equiv="Content-Type" content="text/html; charset=<%= attr :encoding %>">
65
+ <meta name="generator" content="Asciidoctor <%= attr 'asciidoctor-version' %>">
66
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"><%
67
+ if attr? :description %>
68
+ <meta name="description" content="<%= attr :description %>"><%
69
+ end
70
+ if attr? :keywords %>
71
+ <meta name="keywords" content="<%= attr :keywords %>"><%
72
+ end %>
73
+ <title><%= doctitle %></title><%
74
+ if DEFAULT_STYLESHEET_KEYS.include?(attr 'stylesheet')
75
+ if @safe >= SafeMode::SECURE || (attr? 'linkcss') %>
76
+ <link rel="stylesheet" href="<%= normalize_web_path(DEFAULT_STYLESHEET_NAME, (attr :stylesdir, '')) %>"><%
77
+ else %>
78
+ <style>
79
+ <%= ::Asciidoctor::HTML5.default_asciidoctor_stylesheet %>
80
+ </style><%
81
+ end
82
+ elsif attr? :stylesheet
83
+ if attr? 'linkcss' %>
84
+ <link rel="stylesheet" href="<%= normalize_web_path((attr :stylesheet), (attr :stylesdir, '')) %>"><%
85
+ else %>
86
+ <style>
87
+ <%= read_asset normalize_system_path((attr :stylesheet), (attr :stylesdir, '')), true %>
88
+ </style><%
89
+ end
90
+ end
91
+ if attr? 'icons', 'font'
92
+ 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"><%
94
+ else %>
95
+ <link rel="stylesheet" href="<%= normalize_web_path(%(\#{attr 'iconfont-name', 'font-awesome'}.css), (attr 'stylesdir', '')) %>"><%
96
+ end
97
+ end
98
+ case attr 'source-highlighter'
99
+ when 'coderay'
100
+ if (attr 'coderay-css', 'class') == 'class' %>
101
+ <style>
102
+ <%= ::Asciidoctor::HTML5.default_coderay_stylesheet %>
103
+ </style><%
104
+ end
105
+ when 'highlightjs', 'highlight.js' %>
106
+ <link rel="stylesheet" href="<%= attr :highlightjsdir, 'http://cdnjs.cloudflare.com/ajax/libs/highlight.js/7.3' %>/styles/<%= attr 'highlightjs-theme', 'default' %>.min.css">
107
+ <script src="<%= attr :highlightjsdir, 'http://cdnjs.cloudflare.com/ajax/libs/highlight.js/7.3' %>/highlight.min.js"></script>
108
+ <script>hljs.initHighlightingOnLoad()</script><%
109
+ when 'prettify' %>
110
+ <link rel="stylesheet" href="<%= attr 'prettifydir', 'http://cdnjs.cloudflare.com/ajax/libs/prettify/r298' %>/<%= attr 'prettify-theme', 'prettify' %>.min.css">
111
+ <script src="<%= attr 'prettifydir', 'http://cdnjs.cloudflare.com/ajax/libs/prettify/r298' %>/prettify.min.js"></script>
112
+ <script>document.addEventListener('DOMContentLoaded', prettyPrint)</script><%
113
+ end %><%= (docinfo_content = docinfo).empty? ? nil : %(
114
+ \#{docinfo_content}) %>
115
+ </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 %>><%
117
+ unless noheader %>
118
+ <div id="header"><%
119
+ if has_header?
120
+ unless notitle %>
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><%
127
+ end
128
+ end
129
+ if attr? :revnumber %>
130
+ <span id="revnumber">version <%= attr :revnumber %><%= (attr? :revdate) ? ',' : '' %></span><%
131
+ end
132
+ if attr? :revdate %>
133
+ <span id="revdate"><%= attr :revdate %></span><%
134
+ end
135
+ if attr? :revremark %>
136
+ <br><span id="revremark"><%= attr :revremark %></span><%
137
+ end
138
+ end
139
+ if (attr? :toc) && (attr? 'toc-placement', 'auto') %>
140
+ <div id="toc" class="<%= attr 'toc-class', 'toc' %>">
141
+ <div id="toctitle"><%= attr 'toc-title' %></div>
121
142
  <%= template.class.outline(self, (attr :toclevels, 2).to_i) %>
122
- </div>
123
- <% end %>
124
- </div>
125
- <% end %>
126
- <div id="content">
143
+ </div><%
144
+ end %>
145
+ </div><%
146
+ end %>
147
+ <div id="content">
127
148
  <%= content %>
128
- </div>
129
- <% unless !footnotes? || attr?(:nofootnotes) %><div id="footnotes">
130
- <hr>
131
- <% footnotes.each do |fn| %>
132
- <div class="footnote" id="_footnote_<%= fn.index %>">
133
- <a href="#_footnoteref_<%= fn.index %>"><%= fn.index %></a>. <%= fn.text %>
134
- </div>
135
- <% end %>
136
- </div>
137
- <% end %>
138
- <div id="footer">
139
- <div id="footer-text">
140
- <% if attr? :revnumber %>Version <%= attr :revnumber %><br><% end %>
141
- Last updated <%= attr :docdatetime %>
142
- </div>
143
- </div>
144
- </body>
149
+ </div><%
150
+ unless !footnotes? || (attr? :nofootnotes) %>
151
+ <div id="footnotes">
152
+ <hr><%
153
+ footnotes.each do |fn| %>
154
+ <div class="footnote" id="_footnote_<%= fn.index %>">
155
+ <a href="#_footnoteref_<%= fn.index %>"><%= fn.index %></a>. <%= fn.text %>
156
+ </div><%
157
+ end %>
158
+ </div><%
159
+ end %>
160
+ <div id="footer">
161
+ <div id="footer-text"><%
162
+ if attr? :revnumber %>
163
+ Version <%= attr :revnumber %><br><%
164
+ end %>
165
+ Last updated <%= attr :docdatetime %>
166
+ </div>
167
+ </div>
168
+ </body>
145
169
  </html>
146
170
  EOS
147
171
  end
@@ -152,7 +176,7 @@ class EmbeddedTemplate < BaseTemplate
152
176
  @template ||= @eruby.new <<-EOS
153
177
  <%#encoding:UTF-8%><% unless notitle || !has_header? %><h1#{id}><%= header.title %></h1>
154
178
  <% end %><%= content %>
155
- <% unless !footnotes? || attr?(:nofootnotes) %><div id="footnotes">
179
+ <% unless !footnotes? || (attr? :nofootnotes) %><div id="footnotes">
156
180
  <hr>
157
181
  <% footnotes.each do |fn| %>
158
182
  <div class="footnote" id="_footnote_<%= fn.index %>">
@@ -168,12 +192,12 @@ class BlockTocTemplate < BaseTemplate
168
192
  def result(node)
169
193
  doc = node.document
170
194
 
171
- return '' unless doc.attr?('toc')
195
+ return '' unless (doc.attr? 'toc')
172
196
 
173
197
  if node.id
174
198
  id_attr = %( id="#{node.id}")
175
199
  title_id_attr = ''
176
- elsif doc.embedded? || !doc.attr?('toc-placement', 'auto')
200
+ elsif doc.embedded? || !(doc.attr? 'toc-placement')
177
201
  id_attr = ' id="toc"'
178
202
  title_id_attr = ' id="toctitle"'
179
203
  else
@@ -181,13 +205,13 @@ class BlockTocTemplate < BaseTemplate
181
205
  title_id_attr = ''
182
206
  end
183
207
  title = node.title? ? node.title : (doc.attr 'toc-title')
184
- levels = node.attr?('levels') ? node.attr('levels').to_i : doc.attr('toclevels', 2).to_i
185
- role = node.attr?('role') ? node.attr('role') : doc.attr('toc-class', 'toc')
208
+ 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')
186
210
 
187
- %(\n<div#{id_attr} class="#{role}">
211
+ %(<div#{id_attr} class="#{role}">
188
212
  <div#{title_id_attr} class="title">#{title}</div>
189
213
  #{DocumentTemplate.outline(doc, levels)}
190
- </div>)
214
+ </div>\n)
191
215
  end
192
216
 
193
217
  def template
@@ -196,12 +220,23 @@ class BlockTocTemplate < BaseTemplate
196
220
  end
197
221
 
198
222
  class BlockPreambleTemplate < BaseTemplate
223
+ def toc(node)
224
+ if (node.attr? 'toc') && (node.attr? 'toc-placement', 'preamble')
225
+ %(\n<div id="toc" class="#{node.attr 'toc-class', 'toc'}">
226
+ <div id="toctitle">#{node.attr 'toc-title'}</div>
227
+ #{DocumentTemplate.outline(node.document, (node.attr 'toclevels', 2).to_i)}
228
+ </div>)
229
+ else
230
+ ''
231
+ end
232
+ end
233
+
199
234
  def template
200
235
  @template ||= @eruby.new <<-EOS
201
236
  <%#encoding:UTF-8%><div id="preamble">
202
- <div class="sectionbody">
237
+ <div class="sectionbody">
203
238
  <%= content %>
204
- </div>
239
+ </div><%= template.toc(self) %>
205
240
  </div>
206
241
  EOS
207
242
  end
@@ -215,30 +250,43 @@ class SectionTemplate < BaseTemplate
215
250
  slevel = 1
216
251
  end
217
252
  htag = "h#{slevel + 1}"
218
- id = sec.id && " id=\"#{sec.id}\""
253
+ id = anchor = link_start = link_end = nil
254
+ if sec.id
255
+ id = %( id="#{sec.id}")
256
+ if sec.document.attr? 'sectanchors'
257
+ #if sec.document.attr? 'icons', 'font'
258
+ # anchor = %(<a class="anchor" href="##{sec.id}"><i class="icon-anchor"></i></a>)
259
+ #else
260
+ anchor = %(<a class="anchor" href="##{sec.id}"></a>)
261
+ #end
262
+ elsif sec.document.attr? 'sectlinks'
263
+ link_start = %(<a class="link" href="##{sec.id}">)
264
+ link_end = '</a>'
265
+ end
266
+ end
219
267
 
220
268
  if slevel == 0
221
- %(<h1#{id}>#{sec.title}</h1>
222
- #{sec.content})
269
+ %(<h1#{id} class="sect0">#{anchor}#{link_start}#{sec.title}#{link_end}</h1>
270
+ #{sec.content}\n)
223
271
  else
224
- role = sec.attr?('role') ? " #{sec.attr('role')}" : nil
225
- if !sec.special && (sec.attr? 'numbered') && slevel < 4
272
+ role = (sec.attr? 'role') ? " #{sec.attr 'role'}" : nil
273
+ if !sec.special && (sec.document.attr? 'numbered') && slevel < 4
226
274
  sectnum = "#{sec.sectnum} "
227
275
  else
228
276
  sectnum = nil
229
277
  end
230
278
 
231
279
  if slevel == 1
232
- content = %( <div class="sectionbody">
280
+ content = %(<div class="sectionbody">
233
281
  #{sec.content}
234
- </div>)
282
+ </div>)
235
283
  else
236
284
  content = sec.content
237
285
  end
238
286
  %(<div class="sect#{slevel}#{role}">
239
- <#{htag}#{id}>#{sectnum}#{sec.attr 'caption'}#{sec.title}</#{htag}>
287
+ <#{htag}#{id}>#{anchor}#{link_start}#{sectnum}#{sec.caption}#{sec.title}#{link_end}</#{htag}>
240
288
  #{content}
241
- </div>)
289
+ </div>\n)
242
290
  end
243
291
  end
244
292
 
@@ -259,69 +307,103 @@ class BlockDlistTemplate < BaseTemplate
259
307
  def template
260
308
  @template ||= @eruby.new <<-EOS
261
309
  <%#encoding:UTF-8%><%
262
- if attr? :style, 'qanda' %>
263
- <div#{id} class="qlist#{style_class}#{role_class}">
264
- #{title_div}
265
- <ol>
266
- <% content.each do |dt, dd| %>
267
- <li>
268
- <p><em><%= dt.text %></em></p>
269
- <% unless dd.nil? %>
270
- <% if dd.text? %>
271
- <p><%= dd.text %></p>
272
- <% end %>
273
- <% if dd.blocks? %>
274
- <%= dd.content %>
275
- <% end %>
276
- <% end %>
277
- </li>
278
- <% end %>
279
- </ol>
280
- </div>
281
- <% elsif attr? :style, 'horizontal' %>
282
- <div#{id} class="hdlist#{role_class}">
283
- #{title_div}
284
- <table>
285
- <colgroup>
286
- <col<% if attr? :labelwidth %> style="width:<%= attr :labelwidth %>%;"<% end %>>
287
- <col<% if attr? :itemwidth %> style="width:<%= attr :itemwidth %>%;"<% end %>>
288
- </colgroup>
289
- <% content.each do |dt, dd| %>
290
- <tr>
291
- <td class="hdlist1<% if attr? 'strong-option' %> strong<% end %>">
292
- <%= dt.text %>
293
- <br>
294
- </td>
295
- <td class="hdlist2"><% unless dd.nil? %><% if dd.text? %>
296
- <p style="margin-top: 0;"><%= dd.text %></p><% end %><% if dd.blocks? %>
297
- <%= dd.content %><% end %><% end %>
298
- </td>
299
- </tr>
300
- <% end %>
301
- </table>
302
- </div>
303
- <% else %>
304
- <div#{id} class="dlist#{style_class}#{role_class}">
305
- #{title_div}
306
- <dl>
307
- <% content.each do |dt, dd| %>
308
- <dt<% if !(attr? :style) %> class="hdlist1"<% end %>>
309
- <%= dt.text %>
310
- </dt>
311
- <% unless dd.nil? %>
312
- <dd>
313
- <% if dd.text? %>
314
- <p><%= dd.text %></p>
315
- <% end %>
316
- <% if dd.blocks? %>
317
- <%= dd.content %>
318
- <% end %>
319
- </dd>
320
- <% end %>
321
- <% end %>
322
- </dl>
323
- </div>
324
- <% end %>
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
328
+ else
329
+ continuing = false
330
+ end
331
+ unless dd.nil?
332
+ if dd.text? %>
333
+ <p><%= dd.text %></p><%
334
+ end
335
+ if dd.blocks? %>
336
+ <%= dd.content %><%
337
+ 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><%
374
+ end
375
+ if dd.blocks? %>
376
+ <%= dd.content %><%
377
+ 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><%
402
+ end
403
+ end %>
404
+ </dl>
405
+ </div><%
406
+ end %>
325
407
  EOS
326
408
  end
327
409
  end
@@ -330,14 +412,30 @@ class BlockListingTemplate < BaseTemplate
330
412
  def template
331
413
  @template ||= @eruby.new <<-EOS
332
414
  <%#encoding:UTF-8%><div#{id} class="listingblock#{role_class}">
333
- #{title_div :caption => true}
334
- <div class="content monospaced">
335
- <% if attr? :style, 'source' %>
336
- <pre class="highlight<% if attr? 'source-highlighter', 'coderay' %> CodeRay<% end %>"><code#{attribute('class', :language)}><%= template.preserve_endlines(content, self) %></code></pre>
337
- <% else %>
338
- <pre><%= template.preserve_endlines(content, self) %></pre>
339
- <% end %>
340
- </div>
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>
341
439
  </div>
342
440
  EOS
343
441
  end
@@ -347,10 +445,10 @@ class BlockLiteralTemplate < BaseTemplate
347
445
  def template
348
446
  @template ||= @eruby.new <<-EOS
349
447
  <%#encoding:UTF-8%><div#{id} class="literalblock#{role_class}">
350
- #{title_div}
351
- <div class="content monospaced">
352
- <pre><%= template.preserve_endlines(content, self) %></pre>
353
- </div>
448
+ #{title_div}
449
+ <div class="content monospaced">
450
+ <pre><%= template.preserve_endlines(content, self) %></pre>
451
+ </div>
354
452
  </div>
355
453
  EOS
356
454
  end
@@ -360,21 +458,23 @@ class BlockAdmonitionTemplate < BaseTemplate
360
458
  def template
361
459
  @template ||= @eruby.new <<-EOS
362
460
  <%#encoding:UTF-8%><div#{id} class="admonitionblock <%= attr :name %>#{role_class}">
363
- <table>
364
- <tr>
365
- <td class="icon">
366
- <% if attr? :icons %>
367
- <img src="<%= icon_uri(attr :name) %>" alt="<%= attr :caption %>">
368
- <% else %>
369
- <div class="title"><%= attr :caption %></div>
370
- <% end %>
371
- </td>
372
- <td class="content">
373
- #{title_div}
374
- <%= content %>
375
- </td>
376
- </tr>
377
- </table>
461
+ <table>
462
+ <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 %>
471
+ </td>
472
+ <td class="content">
473
+ #{title_div}
474
+ <%= content %>
475
+ </td>
476
+ </tr>
477
+ </table>
378
478
  </div>
379
479
  EOS
380
480
  end
@@ -382,14 +482,14 @@ end
382
482
 
383
483
  class BlockParagraphTemplate < BaseTemplate
384
484
  def paragraph(id, role, title, content)
385
- %(<div#{id && " id=\"#{id}\""} class=\"paragraph#{role && " #{role}"}\">#{title && "
386
- <div class=\"title\">#{title}</div>"}
387
- <p>#{content}</p>
388
- </div>)
485
+ %(<div#{id && " id=\"#{id}\""} class="paragraph#{role && " #{role}"}">#{title && "
486
+ <div class=\"title\">#{title}</div>"}
487
+ <p>#{content}</p>
488
+ </div>\n)
389
489
  end
390
490
 
391
491
  def result(node)
392
- paragraph(node.id, node.attr('role'), (node.title? ? node.title : nil), node.content)
492
+ paragraph(node.id, (node.attr 'role'), (node.title? ? node.title : nil), node.content)
393
493
  end
394
494
 
395
495
  def template
@@ -401,10 +501,10 @@ class BlockSidebarTemplate < BaseTemplate
401
501
  def template
402
502
  @template ||= @eruby.new <<-EOS
403
503
  <%#encoding:UTF-8%><div#{id} class="sidebarblock#{role_class}">
404
- <div class="content">
405
- #{title_div}
504
+ <div class="content">
505
+ #{title_div}
406
506
  <%= content %>
407
- </div>
507
+ </div>
408
508
  </div>
409
509
  EOS
410
510
  end
@@ -414,25 +514,48 @@ class BlockExampleTemplate < BaseTemplate
414
514
  def template
415
515
  @template ||= @eruby.new <<-EOS
416
516
  <%#encoding:UTF-8%><div#{id} class="exampleblock#{role_class}">
417
- #{title_div :caption => true}
418
- <div class="content">
517
+ #{title_div :caption => true}
518
+ <div class="content">
419
519
  <%= content %>
420
- </div>
520
+ </div>
421
521
  </div>
422
522
  EOS
423
523
  end
424
524
  end
425
525
 
426
526
  class BlockOpenTemplate < BaseTemplate
427
- def template
428
- @template ||= @eruby.new <<-EOS
429
- <%#encoding:UTF-8%><div#{id} class="openblock#{role_class}">
430
- #{title_div}
431
- <div class="content">
432
- <%= content %>
433
- </div>
527
+ def result(node)
528
+ open_block(node, node.id, (node.attr 'style', nil, false), (node.attr 'role'), node.title? ? node.title : nil, node.content)
529
+ end
530
+
531
+ def open_block(node, id, style, role, title, content)
532
+ 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.'
535
+ ''
536
+ else
537
+ %(<div#{id && " id=\"#{id}\""} class="quoteblock abstract#{role && " #{role}"}">#{title &&
538
+ "<div class=\"title\">#{title}</div>"}
539
+ <blockquote>
540
+ #{content}
541
+ </blockquote>
542
+ </div>\n)
543
+ 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.'
546
+ ''
547
+ else
548
+ %(<div#{id && " id=\"#{id}\""} class="openblock#{style != 'open' ? " #{style}" : ''}#{role && " #{role}"}">#{title &&
549
+ "<div class=\"title\">#{title}</div>"}
550
+ <div class="content">
551
+ #{content}
434
552
  </div>
435
- EOS
553
+ </div>\n)
554
+ end
555
+ end
556
+
557
+ def template
558
+ :invoke_result
436
559
  end
437
560
  end
438
561
 
@@ -446,21 +569,23 @@ class BlockQuoteTemplate < BaseTemplate
446
569
  def template
447
570
  @template ||= @eruby.new <<-EOS
448
571
  <%#encoding:UTF-8%><div#{id} class="quoteblock#{role_class}">
449
- #{title_div}
450
- <blockquote>
572
+ #{title_div}
573
+ <blockquote>
451
574
  <%= content %>
452
- </blockquote>
453
- <div class="attribution">
454
- <% if attr? :citetitle %>
455
- <cite><%= attr :citetitle %></cite>
456
- <% end %>
457
- <% if attr? :attribution %>
458
- <% if attr? :citetitle %>
459
- <br>
460
- <% end %>
461
- <%= "&#8212; \#{attr :attribution}" %>
462
- <% end %>
463
- </div>
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 %>
464
589
  </div>
465
590
  EOS
466
591
  end
@@ -470,19 +595,21 @@ class BlockVerseTemplate < BaseTemplate
470
595
  def template
471
596
  @template ||= @eruby.new <<-EOS
472
597
  <%#encoding:UTF-8%><div#{id} class="verseblock#{role_class}">
473
- #{title_div}
474
- <pre class="content"><%= template.preserve_endlines(content, self) %></pre>
475
- <div class="attribution">
476
- <% if attr? :citetitle %>
477
- <cite><%= attr :citetitle %></cite>
478
- <% end %>
479
- <% if attr? :attribution %>
480
- <% if attr? :citetitle %>
481
- <br>
482
- <% end %>
483
- <%= "&#8212; \#{attr :attribution}" %>
484
- <% end %>
485
- </div>
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 %>
486
613
  </div>
487
614
  EOS
488
615
  end
@@ -492,37 +619,38 @@ class BlockUlistTemplate < BaseTemplate
492
619
  def template
493
620
  @template ||= @eruby.new <<-EOS
494
621
  <%#encoding:UTF-8%><div#{id} class="ulist#{style_class}#{role_class}">
495
- #{title_div}
496
- <ul>
497
- <% content.each do |item| %>
498
- <li>
499
- <p><%= item.text %></p>
500
- <% if item.blocks? %>
501
- <%= item.content %>
502
- <% end %>
503
- </li>
504
- <% end %>
505
- </ul>
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>
506
633
  </div>
507
634
  EOS
508
635
  end
509
636
  end
510
637
 
511
638
  class BlockOlistTemplate < BaseTemplate
639
+
512
640
  def template
513
641
  @template ||= @eruby.new <<-EOS
514
- <%#encoding:UTF-8%><div#{id} class="olist#{style_class}#{role_class}">
515
- #{title_div}
516
- <ol class="<%= attr :style %>"#{attribute('start', :start)}>
517
- <% content.each do |item| %>
518
- <li>
519
- <p><%= item.text %></p>
520
- <% if item.blocks? %>
521
- <%= item.content %>
522
- <% end %>
523
- </li>
524
- <% end %>
525
- </ol>
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>
526
654
  </div>
527
655
  EOS
528
656
  end
@@ -532,25 +660,28 @@ class BlockColistTemplate < BaseTemplate
532
660
  def template
533
661
  @template ||= @eruby.new <<-EOS
534
662
  <%#encoding:UTF-8%><div#{id} class="colist#{style_class}#{role_class}">
535
- #{title_div}
536
- <% if attr? :icons %>
537
- <table>
538
- <% content.each_with_index do |item, i| %>
539
- <tr>
540
- <td><img src="<%= icon_uri("callouts/\#{i + 1}") %>" alt="<%= i + 1 %>"></td>
541
- <td><%= item.text %></td>
542
- </tr>
543
- <% end %>
544
- </table>
545
- <% else %>
546
- <ol>
547
- <% content.each do |item| %>
548
- <li>
549
- <p><%= item.text %></p>
550
- </li>
551
- <% end %>
552
- </ol>
553
- <% end %>
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 %>
554
685
  </div>
555
686
  EOS
556
687
  end
@@ -561,42 +692,56 @@ class BlockTableTemplate < BaseTemplate
561
692
  @template ||= @eruby.new <<-EOS
562
693
  <%#encoding:UTF-8%><table#{id} class="tableblock frame-<%= attr :frame, 'all' %> grid-<%= attr :grid, 'all'%>#{role_class}" style="<%
563
694
  if !(attr? 'autowidth-option') %>width:<%= attr :tablepcwidth %>%; <% end %><%
564
- if attr? :float %>float: <%= attr :float %>; <% end %>">
565
- <% if title? %>
566
- <caption class="title"><% unless @caption.nil? %><%= @caption %><% end %><%= title %></caption>
567
- <% end %>
568
- <% if (attr :rowcount) >= 0 %>
569
- <colgroup>
570
- <% if attr? 'autowidth-option' %>
571
- <% @columns.each do %>
572
- <col>
573
- <% end %>
574
- <% else %>
575
- <% @columns.each do |col| %>
576
- <col style="width:<%= col.attr :colpcwidth %>%;">
577
- <% end %>
578
- <% end %>
579
- </colgroup>
580
- <% [:head, :foot, :body].select {|tsec| !@rows[tsec].empty? }.each do |tsec| %>
581
- <t<%= tsec %>>
582
- <% @rows[tsec].each do |row| %>
583
- <tr>
584
- <% row.each do |cell| %>
585
- <<%= tsec == :head ? 'th' : 'td' %> class="tableblock halign-<%= cell.attr :halign %> valign-<%= cell.attr :valign %>"#{attribute('colspan', 'cell.colspan')}#{attribute('rowspan', 'cell.rowspan')}><%
586
- if tsec == :head %><%= cell.text %><% else %><%
587
- case cell.attr(:style)
588
- when :asciidoc %><div><%= cell.content %></div><%
589
- when :verse %><div class="verse"><%= template.preserve_endlines(cell.text, self) %></div><%
590
- when :literal %><div class="literal monospaced"><pre><%= template.preserve_endlines(cell.text, self) %></pre></div><%
591
- when :header %><% cell.content.each do |text| %><p class="tableblock header"><%= text %></p><% end %><%
592
- else %><% cell.content.each do |text| %><p class="tableblock"><%= text %></p><% end %><%
593
- end %><% end %></<%= tsec == :head ? 'th' : 'td' %>>
594
- <% end %>
595
- </tr>
596
- <% end %>
597
- </t<%= tsec %>>
598
- <% end %>
599
- <% end %>
695
+ if attr? :float %>float: <%= attr :float %>; <% end %>"><%
696
+ if title? %>
697
+ <caption class="title"><% unless @caption.nil? %><%= @caption %><% end %><%= title %></caption><%
698
+ end
699
+ if (attr :rowcount) >= 0 %>
700
+ <colgroup><%
701
+ if attr? 'autowidth-option'
702
+ @columns.each do %>
703
+ <col><%
704
+ end
705
+ else
706
+ @columns.each do |col| %>
707
+ <col style="width:<%= col.attr :colpcwidth %>%;"><%
708
+ end
709
+ end %>
710
+ </colgroup><%
711
+ [:head, :foot, :body].select {|tsec| !@rows[tsec].empty? }.each do |tsec| %>
712
+ <t<%= tsec %>><%
713
+ @rows[tsec].each do |row| %>
714
+ <tr><%
715
+ row.each do |cell| %>
716
+ <<%= tsec == :head ? 'th' : 'td' %> class="tableblock halign-<%= cell.attr :halign %> valign-<%= cell.attr :valign %>"#{attribute('colspan', 'cell.colspan')}#{attribute('rowspan', 'cell.rowspan')}<%
717
+ cell_content = ''
718
+ if tsec == :head
719
+ cell_content = cell.text
720
+ else
721
+ case (cell.attr 'style', nil, false)
722
+ when :asciidoc
723
+ cell_content = %(<div>\#{cell.content}</div>)
724
+ when :verse
725
+ cell_content = %(<div class="verse">\#{template.preserve_endlines(cell.text, self)}</div>)
726
+ when :literal
727
+ cell_content = %(<div class="literal monospaced"><pre>\#{template.preserve_endlines(cell.text, self)}</pre></div>)
728
+ when :header
729
+ cell.content.each do |text|
730
+ cell_content = %(\#{cell_content}<p class="tableblock header">\#{text}</p>)
731
+ end
732
+ else
733
+ cell.content.each do |text|
734
+ cell_content = %(\#{cell_content}<p class="tableblock">\#{text}</p>)
735
+ end
736
+ end
737
+ end %><%= (@document.attr? 'cellbgcolor') ? %( style="background-color:\#{@document.attr 'cellbgcolor'};") : nil
738
+ %>><%= cell_content %></<%= tsec == :head ? 'th' : 'td' %>><%
739
+ end %>
740
+ </tr><%
741
+ end %>
742
+ </t<%= tsec %>><%
743
+ end
744
+ end %>
600
745
  </table>
601
746
  EOS
602
747
  end
@@ -605,17 +750,18 @@ end
605
750
  class BlockImageTemplate < BaseTemplate
606
751
  def template
607
752
  @template ||= @eruby.new <<-EOS
608
- <%#encoding:UTF-8%><div#{id} class="imageblock#{style_class}#{role_class}"<% if (attr? :align) || (attr? :float)
609
- %> style="<% if attr? :align %>text-align: <%= attr :align %><% if attr? :float %>; <% end %><% end %><% if attr? :float %>float: <%= attr :float %><% end %>"<% end
610
- %>>
611
- <div class="content">
612
- <% if attr? :link %>
613
- <a class="image" href="<%= attr :link %>"><img src="<%= image_uri(attr :target) %>" alt="<%= attr :alt %>"#{attribute('width', :width)}#{attribute('height', :height)}></a>
614
- <% else %>
615
- <img src="<%= image_uri(attr :target) %>" alt="<%= attr :alt %>"#{attribute('width', :width)}#{attribute('height', :height)}>
616
- <% end %>
617
- </div>
618
- #{title_div :caption => true}
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}
619
765
  </div>
620
766
  EOS
621
767
  end
@@ -625,15 +771,15 @@ class BlockAudioTemplate < BaseTemplate
625
771
  def template
626
772
  @template ||= @eruby.new <<-EOS
627
773
  <%#encoding:UTF-8%><div#{id} class="audioblock#{style_class}#{role_class}">
628
- #{title_div :caption => true}
629
- <div class="content">
630
- <audio src="<%= media_uri(attr :target) %>"<% if
631
- attr? 'autoplay-option' %> autoplay<% end %><%
632
- unless attr? 'nocontrols-option' %> controls<% end %><%
633
- if attr? 'loop-option' %> loop<% end %>>
634
- Your browser does not support the audio tag.
635
- </audio>
636
- </div>
774
+ #{title_div :caption => true}
775
+ <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 %>>
780
+ Your browser does not support the audio tag.
781
+ </audio>
782
+ </div>
637
783
  </div>
638
784
  EOS
639
785
  end
@@ -643,16 +789,16 @@ class BlockVideoTemplate < BaseTemplate
643
789
  def template
644
790
  @template ||= @eruby.new <<-EOS
645
791
  <%#encoding:UTF-8%><div#{id} class="videoblock#{style_class}#{role_class}">
646
- #{title_div :caption => true}
647
- <div class="content">
648
- <video src="<%= media_uri(attr :target) %>"#{attribute('width', :width)}#{attribute('height', :height)}<%
649
- if attr? 'poster' %> poster="<%= media_uri(attr :poster) %>"<% end %><%
650
- if attr? 'autoplay-option' %> autoplay<% end %><%
651
- unless attr? 'nocontrols-option' %> controls<% end %><%
652
- if attr? 'loop-option' %> loop<% end %>>
653
- Your browser does not support the video tag.
654
- </video>
655
- </div>
792
+ #{title_div :caption => true}
793
+ <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 %>>
799
+ Your browser does not support the video tag.
800
+ </video>
801
+ </div>
656
802
  </div>
657
803
  EOS
658
804
  end
@@ -670,7 +816,7 @@ end
670
816
 
671
817
  class BlockPageBreakTemplate < BaseTemplate
672
818
  def result(node)
673
- '<div style="page-break-after: always;"></div>'
819
+ %(<div style="page-break-after: always;"></div>\n)
674
820
  end
675
821
 
676
822
  def template
@@ -680,7 +826,7 @@ end
680
826
 
681
827
  class InlineBreakTemplate < BaseTemplate
682
828
  def result(node)
683
- "#{node.text}<br>"
829
+ %(#{node.text}<br>\n)
684
830
  end
685
831
 
686
832
  def template
@@ -690,7 +836,9 @@ end
690
836
 
691
837
  class InlineCalloutTemplate < BaseTemplate
692
838
  def result(node)
693
- if node.attr? 'icons'
839
+ if node.attr? 'icons', 'font'
840
+ %(<i class="conum">#{node.text}</i>)
841
+ elsif node.attr? 'icons'
694
842
  src = node.icon_uri("callouts/#{node.text}")
695
843
  %(<img src="#{src}" alt="#{node.text}">)
696
844
  else
@@ -706,7 +854,7 @@ end
706
854
  class InlineQuotedTemplate < BaseTemplate
707
855
  NO_TAGS = ['', '']
708
856
 
709
- QUOTED_TAGS = {
857
+ QUOTE_TAGS = {
710
858
  :emphasis => ['<em>', '</em>'],
711
859
  :strong => ['<strong>', '</strong>'],
712
860
  :monospaced => ['<code>', '</code>'],
@@ -717,16 +865,67 @@ class InlineQuotedTemplate < BaseTemplate
717
865
  }
718
866
 
719
867
  def quote_text(text, type, role)
720
- start_tag, end_tag = QUOTED_TAGS[type] || NO_TAGS
868
+ start_tag, end_tag = QUOTE_TAGS[type] || NO_TAGS
721
869
  if role
722
- "#{start_tag}<span class=\"#{role}\">#{text}</span>#{end_tag}"
870
+ if start_tag.start_with? '<'
871
+ %(#{start_tag.chop} class="#{role}">#{text}#{end_tag})
872
+ else
873
+ %(#{start_tag}<span class="#{role}">#{text}</span>#{end_tag})
874
+ end
723
875
  else
724
876
  "#{start_tag}#{text}#{end_tag}"
725
877
  end
726
878
  end
727
879
 
728
880
  def result(node)
729
- quote_text(node.text, node.type, node.attr('role'))
881
+ quote_text(node.text, node.type, (node.attr 'role'))
882
+ end
883
+
884
+ def template
885
+ :invoke_result
886
+ end
887
+ end
888
+
889
+ class InlineButtonTemplate < BaseTemplate
890
+ def result(node)
891
+ %(<b class="button">#{node.text}</b>)
892
+ end
893
+
894
+ def template
895
+ :invoke_result
896
+ end
897
+ end
898
+
899
+ class InlineKbdTemplate < BaseTemplate
900
+ def result(node)
901
+ keys = node.attr 'keys'
902
+ if keys.size == 1
903
+ %(<kbd>#{keys.first}</kbd>)
904
+ else
905
+ key_combo = keys.map{|key| %(<kbd>#{key}</kbd>+) }.join.chop
906
+ %(<kbd class="keyseq">#{key_combo}</kbd>)
907
+ end
908
+ end
909
+
910
+ def template
911
+ :invoke_result
912
+ end
913
+ end
914
+
915
+ class InlineMenuTemplate < BaseTemplate
916
+ def menu(menu, submenus, menuitem)
917
+ if !submenus.empty?
918
+ submenu_path = submenus.map{|submenu| %(<span class="submenu">#{submenu}</span>&#160;&#9656; ) }.join.chop
919
+ %(<span class="menuseq"><span class="menu">#{menu}</span>&#160;&#9656; #{submenu_path} <span class="menuitem">#{menuitem}</span></span>)
920
+ elsif !menuitem.nil?
921
+ %(<span class="menuseq"><span class="menu">#{menu}</span>&#160;&#9656; <span class="menuitem">#{menuitem}</span></span>)
922
+ else
923
+ %(<span class="menu">#{menu}</span>)
924
+ end
925
+ end
926
+
927
+ def result(node)
928
+ menu(node.attr('menu'), node.attr('submenus'), node.attr('menuitem'))
730
929
  end
731
930
 
732
931
  def template
@@ -735,7 +934,7 @@ class InlineQuotedTemplate < BaseTemplate
735
934
  end
736
935
 
737
936
  class InlineAnchorTemplate < BaseTemplate
738
- def anchor(target, text, type, document, window = nil)
937
+ def anchor(target, text, type, document, node)
739
938
  case type
740
939
  when :xref
741
940
  text = document.references[:ids].fetch(target, "[#{target}]") if text.nil?
@@ -743,14 +942,14 @@ class InlineAnchorTemplate < BaseTemplate
743
942
  when :ref
744
943
  %(<a id="#{target}"></a>)
745
944
  when :link
746
- %(<a href="#{target}"#{window && " target=\"#{window}\""}>#{text}</a>)
945
+ %(<a href="#{target}"#{(node.attr? 'role') ? " class=\"#{node.attr 'role'}\"" : nil}#{(node.attr? 'window') ? " target=\"#{node.attr 'window'}\"" : nil}>#{text}</a>)
747
946
  when :bibref
748
947
  %(<a id="#{target}"></a>[#{target}])
749
948
  end
750
949
  end
751
950
 
752
951
  def result(node)
753
- anchor(node.target, node.text, node.type, node.document, (node.type == :link ? node.attr('window') : nil))
952
+ anchor(node.target, node.text, node.type, node.document, node)
754
953
  end
755
954
 
756
955
  def template