Module: Asciidoctor::Revealjs::Converter::Helpers
- Defined in:
- lib/asciidoctor-revealjs/converter.rb
Overview
This module gets mixed in to every node (the context of the template) at the time the node is being converted. The properties and methods in this module effectively become direct members of the template.
Constant Summary collapse
- EOL =
%(\n)
- SliceHintRx =
/ +/
- DEFAULT_TOCLEVELS =
Defaults
2
- DEFAULT_SECTNUMLEVELS =
3
- VOID_ELEMENTS =
%w(area base br col command embed hr img input keygen link meta param source track wbr)
- STEM_EQNUMS_AMS =
'ams'
- STEM_EQNUMS_NONE =
'none'
- STEM_EQNUMS_VALID_VALUES =
[ STEM_EQNUMS_NONE, STEM_EQNUMS_AMS, 'all' ]
- MATHJAX_VERSION =
'3.2.0'
- @@slide_footnotes =
Display footnotes per slide
{}
- @@section_footnotes =
{}
Instance Method Summary collapse
-
#append_link_constraint_attrs(node, attrs = []) ⇒ Object
Copied from asciidoctor/lib/asciidoctor/converter/html5.rb (method is private).
-
#bool_data_attr(val) ⇒ Object
bool_data_attr If the AsciiDoc attribute doesn’t exist, no HTML attribute is added If the AsciiDoc attribute exist and is a true value, HTML attribute is enabled (bool) If the AsciiDoc attribute exist and is a false value, HTML attribute is a false string Ex: a feature is enabled globally but can be disabled using a data- attribute on individual items :revealjs_previewlinks: True then :example.com[Link text, preview=false] Here the template must have data-preview-link=“false” not just no data-preview-link attribute.
- #clear_slide_footnotes ⇒ Object
-
#content_for(key, opts = {}, &block) ⇒ Object
Capture nested template content and register it with the specified key, to be executed at a later time.
-
#content_for?(key) ⇒ Boolean
Checks whether deferred template content has been registered for the specified key.
- #convert_image(node = self) ⇒ Object
- #convert_inline_image(node = self) ⇒ Object
-
#data_attrs(attributes) ⇒ Hash
Extracts data- attributes from the attributes.
-
#encode_attribute_value(val) ⇒ Object
Copied from asciidoctor/lib/asciidoctor/converter/html5.rb (method is private).
-
#format_author(node, author) ⇒ Object
Copied from asciidoctor/lib/asciidoctor/converter/semantic-html5.rb which is not yet shipped.
-
#generate_authors(node) ⇒ Object
Copied from asciidoctor/lib/asciidoctor/converter/semantic-html5.rb which is not yet shipped.
-
#generate_stem(cdn_base) ⇒ String
Generate the Mathjax markup to process STEM expressions.
-
#html5_converter ⇒ Object
Retrieves the built-in html5 converter.
-
#html_tag(name, attributes = {}, content = nil) { ... } ⇒ String
Creates an HTML tag with the given name and optionally attributes.
-
#img_link(node = self, src, content) ⇒ Object
Wrap the <img> element in a <a> element if the link attribute is defined.
- #img_tag(node = self, target, html_attrs) ⇒ Object
-
#in_context(name) ⇒ Object
Copied from asciidoctor/lib/asciidoctor/converter/semantic-html5.rb which is not yet shipped.
-
#inline_text_container(content = nil) ⇒ String
Wrap an inline text in a <span> element if the node contains a role, an id or data- attributes.
-
#resolve_content ⇒ Object
Between delimiters (–) is code taken from asciidoctor-bespoke 1.0.0.alpha.1 Licensed under MIT, Copyright © 2015-2016 Dan Allen and the Asciidoctor Project – Retrieve the converted content, wrap it in a ‘<p>` element if the content_model equals :simple and return the result.
- #revealjs_dependencies(document, node, revealjsdir) ⇒ Object
-
#section_level(sec = self) ⇒ Integer
Returns corrected section level.
-
#section_title(sec = self) ⇒ String
Returns the captioned section’s title, optionally numbered.
- #slice_text(str, active = nil) ⇒ Object
- #slide_footnote(footnote) ⇒ Object
- #slide_footnotes(section) ⇒ Object
- #to_boolean(val) ⇒ Object
-
#to_valid_slidenumber(val) ⇒ Object
false needs to be verbatim everything else is a string.
-
#yield_content(key, opts = {}) ⇒ Object
Evaluates the deferred template content registered with the specified key.
Instance Method Details
#append_link_constraint_attrs(node, attrs = []) ⇒ Object
Copied from asciidoctor/lib/asciidoctor/converter/html5.rb (method is private)
374 375 376 377 378 379 380 381 382 383 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 374 def append_link_constraint_attrs node, attrs = [] rel = 'nofollow' if node.option? 'nofollow' if (window = node.attributes['window']) attrs << %( target="#{window}") attrs << (rel ? %( rel="#{rel} noopener") : ' rel="noopener"') if window == '_blank' || (node.option? 'noopener') elsif rel attrs << %( rel="#{rel}") end attrs end |
#bool_data_attr(val) ⇒ Object
bool_data_attr If the AsciiDoc attribute doesn’t exist, no HTML attribute is added If the AsciiDoc attribute exist and is a true value, HTML attribute is enabled (bool) If the AsciiDoc attribute exist and is a false value, HTML attribute is a false string Ex: a feature is enabled globally but can be disabled using a data- attribute on individual items :revealjs_previewlinks: True then :example.com[Link text, preview=false] Here the template must have data-preview-link=“false” not just no data-preview-link attribute
44 45 46 47 48 49 50 51 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 44 def bool_data_attr val return false unless attr?(val) if attr(val).downcase == 'false' || attr(val) == '0' 'false' else true end end |
#clear_slide_footnotes ⇒ Object
177 178 179 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 177 def @@slide_footnotes = {} end |
#content_for(key, opts = {}, &block) ⇒ Object
Capture nested template content and register it with the specified key, to be executed at a later time.
This method must be invoked using the control code directive (i.e., -). By using a control code directive, the block is set up to append the result directly to the output buffer. (Integrations often hide the distinction between a control code directive and an output directive in this context).
key - The Symbol under which to save the template block. opts - A Hash of options to control processing (default: {}):
* :append - A Boolean that indicates whether to append this block
to others registered with this key (default: false).
* :content - String content to be used if template content is not
provided (optional).
block - The template content (in Slim template syntax).
Examples
- content_for :body
p content
- content_for :body, append: true
p more content
Returns nothing.
335 336 337 338 339 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 335 def content_for key, opts = {}, &block @content = {} unless defined? @content (opts[:append] ? (@content[key] ||= []) : (@content[key] = [])) << (block_given? ? block : lambda { opts[:content] }) nil end |
#content_for?(key) ⇒ Boolean
Checks whether deferred template content has been registered for the specified key.
key - The Symbol under which to look for saved template blocks.
Returns a Boolean indicating whether content has been registered for this key.
346 347 348 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 346 def content_for? key (defined? @content) && (@content.key? key) end |
#convert_image(node = self) ⇒ Object
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 241 def convert_image(node = self) # When the stretch class is present, block images will take the most space # they can take. Setting width and height can override that. # We pinned the 100% to height to avoid aspect ratio breakage and since # widescreen monitors are the most popular, chances are that height will # be the biggest constraint if node.has_role?('stretch') && !(node.attr?(:width) || node.attr?(:height)) height_value = "100%" elsif node.attr? 'height' height_value = node.attr 'height' else height_value = nil end html_attrs = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : '' html_attrs = %(#{html_attrs} height="#{height_value}") if height_value html_attrs = %(#{html_attrs} title="#{node.attr 'title'}") if node.attr? 'title' html_attrs = %(#{html_attrs} style="background: #{node.attr :background}") if node.attr? 'background' img, src = img_tag(node, node.attr('target'), html_attrs) img_link(node, src, img) end |
#convert_inline_image(node = self) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 211 def convert_inline_image(node = self) target = node.target if (node.type || 'image') == 'icon' if (icons = node.document.attr 'icons') == 'font' i_class_attr_val = %(#{node.attr(:set, 'fa')} fa-#{target}) i_class_attr_val = %(#{i_class_attr_val} fa-#{node.attr 'size'}) if node.attr? 'size' if node.attr? 'flip' i_class_attr_val = %(#{i_class_attr_val} fa-flip-#{node.attr 'flip'}) elsif node.attr? 'rotate' i_class_attr_val = %(#{i_class_attr_val} fa-rotate-#{node.attr 'rotate'}) end attrs = (node.attr? 'title') ? %( title="#{node.attr 'title'}") : '' img = %(<i class="#{i_class_attr_val}"#{attrs}></i>) elsif icons attrs = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : '' attrs = %(#{attrs} height="#{node.attr 'height'}") if node.attr? 'height' attrs = %(#{attrs} title="#{node.attr 'title'}") if node.attr? 'title' img = %(<img src="#{src = node.icon_uri target}" alt="#{encode_attribute_value node.alt}"#{attrs}>) else img = %([#{node.alt}]) end else html_attrs = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : '' html_attrs = %(#{html_attrs} height="#{node.attr 'height'}") if node.attr? 'height' html_attrs = %(#{html_attrs} title="#{node.attr 'title'}") if node.attr? 'title' img, src = img_tag(node, target, html_attrs) end img_link(node, src, img) end |
#data_attrs(attributes) ⇒ Hash
Extracts data- attributes from the attributes.
106 107 108 109 110 111 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 106 def data_attrs(attributes) # key can be an Integer (for positional attributes) attributes.map { |key, value| (key == 'step') ? ['data-fragment-index', value] : [key, value] } .to_h .select { |key, _| key.to_s.start_with?('data-') } end |
#encode_attribute_value(val) ⇒ Object
Copied from asciidoctor/lib/asciidoctor/converter/html5.rb (method is private)
386 387 388 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 386 def encode_attribute_value val (val.include? '"') ? (val.gsub '"', '"') : val end |
#format_author(node, author) ⇒ Object
remove this code when the new converter becomes available in the main gem
Copied from asciidoctor/lib/asciidoctor/converter/semantic-html5.rb which is not yet shipped
411 412 413 414 415 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 411 def node, in_context 'author' do %(<span class="author">#{node.sub_replacements .name}#{.email ? %( #{node.sub_macros .email}) : ''}</span>) end end |
#generate_authors(node) ⇒ Object
remove this code when the new converter becomes available in the main gem
Copied from asciidoctor/lib/asciidoctor/converter/semantic-html5.rb which is not yet shipped
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 392 def node return if node..empty? if node..length == 1 %(<p class="byline"> #{ node, node..first} </p>) else result = ['<ul class="byline">'] node..each do || result << "<li>#{ node, }</li>" end result << '</ul>' result.join Asciidoctor::LF end end |
#generate_stem(cdn_base) ⇒ String
Generate the Mathjax markup to process STEM expressions
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 439 def generate_stem(cdn_base) if attr?(:stem) eqnums_val = attr('eqnums', STEM_EQNUMS_NONE).downcase unless STEM_EQNUMS_VALID_VALUES.include?(eqnums_val) eqnums_val = STEM_EQNUMS_AMS end mathjax_configuration = { tex: { inlineMath: [Asciidoctor::INLINE_MATH_DELIMITERS[:latexmath]], displayMath: [Asciidoctor::BLOCK_MATH_DELIMITERS[:latexmath]], processEscapes: false, tags: eqnums_val, }, options: { ignoreHtmlClass: 'nostem|nolatexmath' }, asciimath: { delimiters: [Asciidoctor::BLOCK_MATH_DELIMITERS[:asciimath]], }, loader: { load: ['input/asciimath', 'output/chtml', 'ui/menu'] } } mathjaxdir = attr('mathjaxdir', "#{cdn_base}/mathjax/#{MATHJAX_VERSION}/es5") %(<script>window.MathJax = #{JSON.generate(mathjax_configuration)};</script>) + %(<script async src="#{mathjaxdir}/tex-mml-chtml.js"></script>) end end |
#html5_converter ⇒ Object
Retrieves the built-in html5 converter.
Returns the instance of the Asciidoctor::Converter::Html5Converter associated with this node.
207 208 209 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 207 def html5_converter converter.instance_variable_get("@delegate_converter") end |
#html_tag(name, attributes = {}, content = nil) { ... } ⇒ String
Creates an HTML tag with the given name and optionally attributes. Can take a block that will run between the opening and closing tags.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 84 def html_tag(name, attributes = {}, content = nil) attrs = attributes.inject([]) do |attrs, (k, v)| next attrs unless v && (v == true || !v.nil_or_empty?) v = v.compact.join(' ') if v.is_a? Array attrs << (v == true ? k : %(#{k}="#{v}")) end attrs_str = attrs.empty? ? '' : ' ' + attrs.join(' ') if VOID_ELEMENTS.include? name.to_s %(<#{name}#{attrs_str}>) else content ||= (yield if block_given?) %(<#{name}#{attrs_str}>#{content}</#{name}>) end end |
#img_link(node = self, src, content) ⇒ Object
Wrap the <img> element in a <a> element if the link attribute is defined
280 281 282 283 284 285 286 287 288 289 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 280 def img_link(node = self, src, content) if (node.attr? 'link') && ((href_attr_val = node.attr 'link') != 'self' || (href_attr_val = src)) if (link_preview_value = bool_data_attr :link_preview) data_preview_attr = %( data-preview-link="#{link_preview_value == true ? "" : link_preview_value}") end return %(<a class="image" href="#{href_attr_val}"#{(append_link_constraint_attrs node).join}#{data_preview_attr}>#{content}</a>) end content end |
#img_tag(node = self, target, html_attrs) ⇒ Object
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 262 def img_tag(node = self, target, html_attrs) if ((node.attr? 'format', 'svg') || (target.include? '.svg')) && node.document.safe < ::Asciidoctor::SafeMode::SECURE if node.option? 'inline' img = (html5_converter.read_svg_contents node, target) || %(<span class="alt">#{node.alt}</span>) elsif node.option? 'interactive' fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri node.attr 'fallback'}" alt="#{encode_attribute_value node.alt}"#{html_attrs}>) : %(<span class="alt">#{node.alt}</span>) img = %(<object type="image/svg+xml" data="#{src = node.image_uri target}"#{html_attrs}>#{fallback}</object>) else img = %(<img src="#{src = node.image_uri target}" alt="#{encode_attribute_value node.alt}"#{html_attrs}>) end else img = %(<img src="#{src = node.image_uri target}" alt="#{encode_attribute_value node.alt}"#{html_attrs}>) end [img, src] end |
#in_context(name) ⇒ Object
remove this code when the new converter becomes available in the main gem
Copied from asciidoctor/lib/asciidoctor/converter/semantic-html5.rb which is not yet shipped
419 420 421 422 423 424 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 419 def in_context name (@convert_context ||= []).push name result = yield @convert_context.pop result end |
#inline_text_container(content = nil) ⇒ String
Wrap an inline text in a <span> element if the node contains a role, an id or data- attributes.
119 120 121 122 123 124 125 126 127 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 119 def inline_text_container(content = nil) data_attrs = data_attrs(@attributes) classes = [role, ('fragment' if (option? :step) || (attr? 'step') || (roles.include? 'step'))].compact if !roles.empty? || !data_attrs.empty? || !@id.nil? html_tag('span', { :id => @id, :class => classes }.merge(data_attrs), (content || (yield if block_given?))) else content || (yield if block_given?) end end |
#resolve_content ⇒ Object
Between delimiters (–) is code taken from asciidoctor-bespoke 1.0.0.alpha.1 Licensed under MIT, Copyright © 2015-2016 Dan Allen and the Asciidoctor Project – Retrieve the converted content, wrap it in a ‘<p>` element if the content_model equals :simple and return the result.
Returns the block content as a String, wrapped inside a ‘<p>` element if the content_model equals `:simple`.
307 308 309 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 307 def resolve_content @content_model == :simple ? %(<p>#{content}</p>) : content end |
#revealjs_dependencies(document, node, revealjsdir) ⇒ Object
291 292 293 294 295 296 297 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 291 def revealjs_dependencies(document, node, revealjsdir) dependencies = [] dependencies << "{ src: '#{revealjsdir}/plugin/zoom/zoom.js', async: true, callback: function () { Reveal.registerPlugin(RevealZoom) } }" unless (node.attr? 'revealjs_plugin_zoom', 'disabled') dependencies << "{ src: '#{revealjsdir}/plugin/notes/notes.js', async: true, callback: function () { Reveal.registerPlugin(RevealNotes) } }" unless (node.attr? 'revealjs_plugin_notes', 'disabled') dependencies << "{ src: '#{revealjsdir}/plugin/search/search.js', async: true, callback: function () { Reveal.registerPlugin(RevealSearch) } }" if (node.attr? 'revealjs_plugin_search', 'enabled') dependencies.join(",\n ") end |
#section_level(sec = self) ⇒ Integer
Returns corrected section level.
136 137 138 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 136 def section_level(sec = self) @_section_level ||= (sec.level == 0 && sec.special) ? 1 : sec.level end |
#section_title(sec = self) ⇒ String
Returns the captioned section’s title, optionally numbered.
193 194 195 196 197 198 199 200 201 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 193 def section_title(sec = self) sectnumlevels = document.attr(:sectnumlevels, DEFAULT_SECTNUMLEVELS).to_i if sec.numbered && !sec. && sec.level <= sectnumlevels [sec.sectnum, sec.].join(' ') else sec. end end |
#slice_text(str, active = nil) ⇒ Object
24 25 26 27 28 29 30 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 24 def slice_text str, active = nil if (active || (active.nil? && (option? :slice))) && (str.include? ' ') (str.split SliceHintRx).map {|line| %(<span class="line">#{line}</span>) }.join EOL else str end end |
#slide_footnote(footnote) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 146 def (footnote) footnote_parent = footnote.parent # footnotes declared on the section title are processed during the parsing/substitution. # as a result, we need to store them to display them on the right slide/section if footnote_parent.instance_of?(::Asciidoctor::Section) footnote_parent_object_id = footnote_parent.object_id section_footnotes = (@@section_footnotes[footnote_parent_object_id] || []) footnote_index = section_footnotes.length + 1 attributes = footnote.attributes.merge({ 'index' => footnote_index }) inline_footnote = Asciidoctor::Inline.new(footnote_parent, footnote.context, footnote.text, :attributes => attributes) section_footnotes << Asciidoctor::Document::Footnote.new(inline_footnote.attr(:index), inline_footnote.id, inline_footnote.text) @@section_footnotes[footnote_parent_object_id] = section_footnotes inline_footnote else parent = footnote.parent until parent == nil || parent.instance_of?(::Asciidoctor::Section) parent = parent.parent end # check if there is any footnote attached on the section title section_footnotes = parent != nil ? @@section_footnotes[parent.object_id] || [] : [] initial_index = footnote.attr(:index) # reset the footnote numbering to 1 on each slide # make sure that if a footnote is used more than once it will use the same index/number = (existing_footnote = @@slide_footnotes[initial_index]) ? existing_footnote.index : @@slide_footnotes.length + section_footnotes.length + 1 attributes = footnote.attributes.merge({ 'index' => }) inline_footnote = Asciidoctor::Inline.new(footnote_parent, footnote.context, footnote.text, :attributes => attributes) @@slide_footnotes[initial_index] = Asciidoctor::Document::Footnote.new(inline_footnote.attr(:index), inline_footnote.id, inline_footnote.text) inline_footnote end end |
#slide_footnotes(section) ⇒ Object
181 182 183 184 185 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 181 def (section) section_object_id = section.object_id section_footnotes = @@section_footnotes[section_object_id] || [] section_footnotes + @@slide_footnotes.values end |
#to_boolean(val) ⇒ Object
32 33 34 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 32 def to_boolean val val && val != 'false' && val.to_s != '0' || false end |
#to_valid_slidenumber(val) ⇒ Object
false needs to be verbatim everything else is a string. Calling side isn’t responsible for quoting so we are doing it here
55 56 57 58 59 60 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 55 def val # corner case: empty is empty attribute which is true return true if val == "" # using to_s here handles both the 'false' string and the false boolean val.to_s == 'false' ? false : "'#{val}'" end |
#yield_content(key, opts = {}) ⇒ Object
Evaluates the deferred template content registered with the specified key.
When the corresponding content_for method is invoked using a control code directive, the block is set up to append the result to the output buffer directly.
key - The Symbol under which to look for template blocks to yield. opts - A Hash of options to control processing (default: {}):
* :drain - A Boolean indicating whether to drain the key of blocks
after calling them (default: true).
Examples
- yield_content :body
Returns nothing (assuming the content has been captured in the context of control code).
366 367 368 369 370 371 |
# File 'lib/asciidoctor-revealjs/converter.rb', line 366 def yield_content key, opts = {} if (defined? @content) && (blks = (opts.fetch :drain, true) ? (@content.delete key) : @content[key]) blks.map {|b| b.call }.join end nil end |