asciidoctor 2.0.0.rc.2 → 2.0.0.rc.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -41,7 +41,49 @@ class Converter::Html5Converter < Converter::Base
41
41
  init_backend_traits basebackend: 'html', filetype: 'html', htmlsyntax: syntax, outfilesuffix: '.html', supports_templates: true
42
42
  end
43
43
 
44
- def document node
44
+ def convert node, transform = node.node_name, opts = nil
45
+ if transform == 'inline_quoted'; return convert_inline_quoted node
46
+ elsif transform == 'paragraph'; return convert_paragraph node
47
+ elsif transform == 'inline_anchor'; return convert_inline_anchor node
48
+ elsif transform == 'section'; return convert_section node
49
+ elsif transform == 'listing'; return convert_listing node
50
+ elsif transform == 'literal'; return convert_literal node
51
+ elsif transform == 'ulist'; return convert_ulist node
52
+ elsif transform == 'olist'; return convert_olist node
53
+ elsif transform == 'dlist'; return convert_dlist node
54
+ elsif transform == 'admonition'; return convert_admonition node
55
+ elsif transform == 'colist'; return convert_colist node
56
+ elsif transform == 'embedded'; return convert_embedded node
57
+ elsif transform == 'example'; return convert_example node
58
+ elsif transform == 'floating_title'; return convert_floating_title node
59
+ elsif transform == 'image'; return convert_image node
60
+ elsif transform == 'inline_break'; return convert_inline_break node
61
+ elsif transform == 'inline_button'; return convert_inline_button node
62
+ elsif transform == 'inline_callout'; return convert_inline_callout node
63
+ elsif transform == 'inline_footnote'; return convert_inline_footnote node
64
+ elsif transform == 'inline_image'; return convert_inline_image node
65
+ elsif transform == 'inline_indexterm'; return convert_inline_indexterm node
66
+ elsif transform == 'inline_kbd'; return convert_inline_kbd node
67
+ elsif transform == 'inline_menu'; return convert_inline_menu node
68
+ elsif transform == 'open'; return convert_open node
69
+ elsif transform == 'page_break'; return convert_page_break node
70
+ elsif transform == 'preamble'; return convert_preamble node
71
+ elsif transform == 'quote'; return convert_quote node
72
+ elsif transform == 'sidebar'; return convert_sidebar node
73
+ elsif transform == 'stem'; return convert_stem node
74
+ elsif transform == 'table'; return convert_table node
75
+ elsif transform == 'thematic_break'; return convert_thematic_break node
76
+ elsif transform == 'verse'; return convert_verse node
77
+ elsif transform == 'video'; return convert_video node
78
+ elsif transform == 'document'; return convert_document node
79
+ elsif transform == 'toc'; return convert_toc node
80
+ elsif transform == 'pass'; return convert_pass node
81
+ elsif transform == 'audio'; return convert_audio node
82
+ else; return super
83
+ end
84
+ end
85
+
86
+ def convert_document node
45
87
  br = %(<br#{slash = @void_element_slash}>)
46
88
  unless (asset_uri_scheme = (node.attr 'asset-uri-scheme', 'https')).empty?
47
89
  asset_uri_scheme = %(#{asset_uri_scheme}:)
@@ -132,10 +174,10 @@ class Converter::Html5Converter < Converter::Base
132
174
  if sectioned && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
133
175
  result << %(<div id="toc" class="#{node.attr 'toc-class', 'toc'}">
134
176
  <div id="toctitle">#{node.attr 'toc-title'}</div>
135
- #{outline node}
177
+ #{convert_outline node}
136
178
  </div>)
137
179
  end
138
- result << (_generate_manname_section node) if node.attr? 'manpurpose'
180
+ result << (generate_manname_section node) if node.attr? 'manpurpose'
139
181
  else
140
182
  if node.header?
141
183
  result << %(<h1>#{node.header.title}</h1>) unless node.notitle
@@ -165,7 +207,7 @@ class Converter::Html5Converter < Converter::Base
165
207
  if sectioned && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
166
208
  result << %(<div id="toc" class="#{node.attr 'toc-class', 'toc'}">
167
209
  <div id="toctitle">#{node.attr 'toc-title'}</div>
168
- #{outline node}
210
+ #{convert_outline node}
169
211
  </div>)
170
212
  end
171
213
  end
@@ -235,7 +277,7 @@ TeX: {#{eqnums_opt}}
235
277
  result.join LF
236
278
  end
237
279
 
238
- def embedded node
280
+ def convert_embedded node
239
281
  result = []
240
282
  if node.doctype == 'manpage'
241
283
  # QUESTION should notitle control the manual page title?
@@ -243,7 +285,7 @@ TeX: {#{eqnums_opt}}
243
285
  id_attr = node.id ? %( id="#{node.id}") : ''
244
286
  result << %(<h1#{id_attr}>#{node.doctitle} Manual Page</h1>)
245
287
  end
246
- result << (_generate_manname_section node) if node.attr? 'manpurpose'
288
+ result << (generate_manname_section node) if node.attr? 'manpurpose'
247
289
  elsif node.header? && !node.notitle
248
290
  id_attr = node.id ? %( id="#{node.id}") : ''
249
291
  result << %(<h1#{id_attr}>#{node.header.title}</h1>)
@@ -252,7 +294,7 @@ TeX: {#{eqnums_opt}}
252
294
  if node.sections? && (node.attr? 'toc') && (toc_p = node.attr 'toc-placement') != 'macro' && toc_p != 'preamble'
253
295
  result << %(<div id="toc" class="toc">
254
296
  <div id="toctitle">#{node.attr 'toc-title'}</div>
255
- #{outline node}
297
+ #{convert_outline node}
256
298
  </div>)
257
299
  end
258
300
 
@@ -272,7 +314,7 @@ TeX: {#{eqnums_opt}}
272
314
  result.join LF
273
315
  end
274
316
 
275
- def outline node, opts = {}
317
+ def convert_outline node, opts = {}
276
318
  return unless node.sections?
277
319
  sectnumlevels = opts[:sectnumlevels] || (node.document.attributes['sectnumlevels'] || 3).to_i
278
320
  toclevels = opts[:toclevels] || (node.document.attributes['toclevels'] || 2).to_i
@@ -299,7 +341,7 @@ TeX: {#{eqnums_opt}}
299
341
  stitle = section.title
300
342
  end
301
343
  stitle = stitle.gsub DropAnchorRx, '' if stitle.include? '<a'
302
- if slevel < toclevels && (child_toc_level = outline section, toclevels: toclevels, sectnumlevels: sectnumlevels)
344
+ if slevel < toclevels && (child_toc_level = convert_outline section, toclevels: toclevels, sectnumlevels: sectnumlevels)
303
345
  result << %(<li><a href="##{section.id}">#{stitle}</a>)
304
346
  result << child_toc_level
305
347
  result << '</li>'
@@ -311,7 +353,7 @@ TeX: {#{eqnums_opt}}
311
353
  result.join LF
312
354
  end
313
355
 
314
- def section node
356
+ def convert_section node
315
357
  doc_attrs = node.document.attributes
316
358
  level = node.level
317
359
  if node.caption
@@ -360,7 +402,7 @@ TeX: {#{eqnums_opt}}
360
402
  end
361
403
  end
362
404
 
363
- def admonition node
405
+ def convert_admonition node
364
406
  id_attr = node.id ? %( id="#{node.id}") : ''
365
407
  name = node.attr 'name'
366
408
  title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
@@ -387,7 +429,7 @@ TeX: {#{eqnums_opt}}
387
429
  </div>)
388
430
  end
389
431
 
390
- def audio node
432
+ def convert_audio node
391
433
  xml = @xml_mode
392
434
  id_attribute = node.id ? %( id="#{node.id}") : ''
393
435
  classes = ['audioblock', node.role].compact
@@ -398,14 +440,14 @@ TeX: {#{eqnums_opt}}
398
440
  time_anchor = (start_t || end_t) ? %(#t=#{start_t || ''}#{end_t ? ",#{end_t}" : ''}) : ''
399
441
  %(<div#{id_attribute}#{class_attribute}>
400
442
  #{title_element}<div class="content">
401
- <audio src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{(node.option? 'autoplay') ? (_append_boolean_attribute 'autoplay', xml) : ''}#{(node.option? 'nocontrols') ? '' : (_append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (_append_boolean_attribute 'loop', xml) : ''}>
443
+ <audio src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{(node.option? 'autoplay') ? (append_boolean_attribute 'autoplay', xml) : ''}#{(node.option? 'nocontrols') ? '' : (append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (append_boolean_attribute 'loop', xml) : ''}>
402
444
  Your browser does not support the audio tag.
403
445
  </audio>
404
446
  </div>
405
447
  </div>)
406
448
  end
407
449
 
408
- def colist node
450
+ def convert_colist node
409
451
  result = []
410
452
  id_attribute = node.id ? %( id="#{node.id}") : ''
411
453
  classes = ['colist', node.style, node.role].compact
@@ -444,7 +486,7 @@ Your browser does not support the audio tag.
444
486
  result.join LF
445
487
  end
446
488
 
447
- def dlist node
489
+ def convert_dlist node
448
490
  result = []
449
491
  id_attribute = node.id ? %( id="#{node.id}") : ''
450
492
 
@@ -527,40 +569,50 @@ Your browser does not support the audio tag.
527
569
  result.join LF
528
570
  end
529
571
 
530
- def example node
572
+ def convert_example node
531
573
  id_attribute = node.id ? %( id="#{node.id}") : ''
532
- title_element = node.title? ? %(<div class="title">#{node.captioned_title}</div>\n) : ''
533
-
534
- %(<div#{id_attribute} class="exampleblock#{(role = node.role) ? " #{role}" : ''}">
574
+ if node.option? 'collapsible'
575
+ class_attribute = node.role ? %( class="#{node.role}") : ''
576
+ summary_element = node.title? ? %(<summary class="title">#{node.title}</summary>) : '<summary class="title">Details</summary>'
577
+ %(<details#{id_attribute}#{class_attribute}#{(node.option? 'open') ? ' open' : ''}>
578
+ #{summary_element}
579
+ <div class="content">
580
+ #{node.content}
581
+ </div>
582
+ </details>)
583
+ else
584
+ title_element = node.title? ? %(<div class="title">#{node.captioned_title}</div>\n) : ''
585
+ %(<div#{id_attribute} class="exampleblock#{(role = node.role) ? " #{role}" : ''}">
535
586
  #{title_element}<div class="content">
536
587
  #{node.content}
537
588
  </div>
538
589
  </div>)
590
+ end
539
591
  end
540
592
 
541
- def floating_title node
593
+ def convert_floating_title node
542
594
  tag_name = %(h#{node.level + 1})
543
595
  id_attribute = node.id ? %( id="#{node.id}") : ''
544
596
  classes = [node.style, node.role].compact
545
597
  %(<#{tag_name}#{id_attribute} class="#{classes.join ' '}">#{node.title}</#{tag_name}>)
546
598
  end
547
599
 
548
- def image node
600
+ def convert_image node
549
601
  target = node.attr 'target'
550
602
  width_attr = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : ''
551
603
  height_attr = (node.attr? 'height') ? %( height="#{node.attr 'height'}") : ''
552
604
  if ((node.attr? 'format', 'svg') || (target.include? '.svg')) && node.document.safe < SafeMode::SECURE &&
553
605
  ((svg = (node.option? 'inline')) || (obj = (node.option? 'interactive')))
554
606
  if svg
555
- img = (_read_svg_contents node, target) || %(<span class="alt">#{node.alt}</span>)
607
+ img = (read_svg_contents node, target) || %(<span class="alt">#{node.alt}</span>)
556
608
  elsif obj
557
- fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri(node.attr 'fallback')}" alt="#{_encode_attribute_value node.alt}"#{width_attr}#{height_attr}#{@void_element_slash}>) : %(<span class="alt">#{node.alt}</span>)
609
+ fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri(node.attr 'fallback')}" alt="#{encode_attribute_value node.alt}"#{width_attr}#{height_attr}#{@void_element_slash}>) : %(<span class="alt">#{node.alt}</span>)
558
610
  img = %(<object type="image/svg+xml" data="#{node.image_uri target}"#{width_attr}#{height_attr}>#{fallback}</object>)
559
611
  end
560
612
  end
561
- img ||= %(<img src="#{node.image_uri target}" alt="#{_encode_attribute_value node.alt}"#{width_attr}#{height_attr}#{@void_element_slash}>)
613
+ img ||= %(<img src="#{node.image_uri target}" alt="#{encode_attribute_value node.alt}"#{width_attr}#{height_attr}#{@void_element_slash}>)
562
614
  if node.attr? 'link'
563
- img = %(<a class="image" href="#{node.attr 'link'}"#{(_append_link_constraint_attrs node).join}>#{img}</a>)
615
+ img = %(<a class="image" href="#{node.attr 'link'}"#{(append_link_constraint_attrs node).join}>#{img}</a>)
564
616
  end
565
617
  id_attr = node.id ? %( id="#{node.id}") : ''
566
618
  classes = ['imageblock']
@@ -576,7 +628,7 @@ Your browser does not support the audio tag.
576
628
  </div>)
577
629
  end
578
630
 
579
- def listing node
631
+ def convert_listing node
580
632
  nowrap = (node.option? 'nowrap') || !(node.document.attr? 'prewrap')
581
633
  if node.style == 'source'
582
634
  lang = node.attr 'language'
@@ -603,7 +655,7 @@ Your browser does not support the audio tag.
603
655
  </div>)
604
656
  end
605
657
 
606
- def literal node
658
+ def convert_literal node
607
659
  id_attribute = node.id ? %( id="#{node.id}") : ''
608
660
  title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
609
661
  nowrap = !(node.document.attr? 'prewrap') || (node.option? 'nowrap')
@@ -614,9 +666,7 @@ Your browser does not support the audio tag.
614
666
  </div>)
615
667
  end
616
668
 
617
- alias pass _content_only
618
-
619
- def stem node
669
+ def convert_stem node
620
670
  id_attribute = node.id ? %( id="#{node.id}") : ''
621
671
  title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
622
672
  open, close = BLOCK_MATH_DELIMITERS[style = node.style.to_sym]
@@ -638,7 +688,7 @@ Your browser does not support the audio tag.
638
688
  </div>)
639
689
  end
640
690
 
641
- def olist node
691
+ def convert_olist node
642
692
  result = []
643
693
  id_attribute = node.id ? %( id="#{node.id}") : ''
644
694
  classes = ['olist', node.style, node.role].compact
@@ -649,7 +699,7 @@ Your browser does not support the audio tag.
649
699
 
650
700
  type_attribute = (keyword = node.list_marker_keyword) ? %( type="#{keyword}") : ''
651
701
  start_attribute = (node.attr? 'start') ? %( start="#{node.attr 'start'}") : ''
652
- reversed_attribute = (node.option? 'reversed') ? (_append_boolean_attribute 'reversed', @xml_mode) : ''
702
+ reversed_attribute = (node.option? 'reversed') ? (append_boolean_attribute 'reversed', @xml_mode) : ''
653
703
  result << %(<ol class="#{node.style}"#{type_attribute}#{start_attribute}#{reversed_attribute}>)
654
704
 
655
705
  node.items.each do |item|
@@ -670,7 +720,7 @@ Your browser does not support the audio tag.
670
720
  result.join LF
671
721
  end
672
722
 
673
- def open node
723
+ def convert_open node
674
724
  if (style = node.style) == 'abstract'
675
725
  if node.parent == node.document && node.document.doctype == 'book'
676
726
  logger.warn 'abstract block cannot be used in a document without a title when doctype is book. Excluding block content.'
@@ -698,11 +748,11 @@ Your browser does not support the audio tag.
698
748
  end
699
749
  end
700
750
 
701
- def page_break node
751
+ def convert_page_break node
702
752
  '<div style="page-break-after: always;"></div>'
703
753
  end
704
754
 
705
- def paragraph node
755
+ def convert_paragraph node
706
756
  if node.role
707
757
  attributes = %(#{node.id ? %[ id="#{node.id}"] : ''} class="paragraph #{node.role}")
708
758
  elsif node.id
@@ -722,12 +772,14 @@ Your browser does not support the audio tag.
722
772
  end
723
773
  end
724
774
 
725
- def preamble node
775
+ alias convert_pass content_only
776
+
777
+ def convert_preamble node
726
778
  if (doc = node.document).attr?('toc-placement', 'preamble') && doc.sections? && (doc.attr? 'toc')
727
779
  toc = %(
728
780
  <div id="toc" class="#{doc.attr 'toc-class', 'toc'}">
729
781
  <div id="toctitle">#{doc.attr 'toc-title'}</div>
730
- #{outline doc}
782
+ #{convert_outline doc}
731
783
  </div>)
732
784
  else
733
785
  toc = ''
@@ -740,7 +792,7 @@ Your browser does not support the audio tag.
740
792
  </div>)
741
793
  end
742
794
 
743
- def quote node
795
+ def convert_quote node
744
796
  id_attribute = node.id ? %( id="#{node.id}") : ''
745
797
  classes = ['quoteblock', node.role].compact
746
798
  class_attribute = %( class="#{classes.join ' '}")
@@ -762,11 +814,11 @@ Your browser does not support the audio tag.
762
814
  </div>)
763
815
  end
764
816
 
765
- def thematic_break node
817
+ def convert_thematic_break node
766
818
  %(<hr#{@void_element_slash}>)
767
819
  end
768
820
 
769
- def sidebar node
821
+ def convert_sidebar node
770
822
  id_attribute = node.id ? %( id="#{node.id}") : ''
771
823
  title_element = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
772
824
  %(<div#{id_attribute} class="sidebarblock#{(role = node.role) ? " #{role}" : ''}">
@@ -776,7 +828,7 @@ Your browser does not support the audio tag.
776
828
  </div>)
777
829
  end
778
830
 
779
- def table node
831
+ def convert_table node
780
832
  result = []
781
833
  id_attribute = node.id ? %( id="#{node.id}") : ''
782
834
  classes = ['tableblock', %(frame-#{node.attr 'frame', 'all', 'table-frame'}), %(grid-#{node.attr 'grid', 'all', 'table-grid'})]
@@ -847,7 +899,7 @@ Your browser does not support the audio tag.
847
899
  result.join LF
848
900
  end
849
901
 
850
- def toc node
902
+ def convert_toc node
851
903
  unless (doc = node.document).attr?('toc-placement', 'macro') && doc.sections? && (doc.attr? 'toc')
852
904
  return '<!-- toc disabled -->'
853
905
  end
@@ -865,11 +917,11 @@ Your browser does not support the audio tag.
865
917
 
866
918
  %(<div#{id_attr} class="#{role}">
867
919
  <div#{title_id_attr} class="title">#{title}</div>
868
- #{outline doc, toclevels: levels}
920
+ #{convert_outline doc, toclevels: levels}
869
921
  </div>)
870
922
  end
871
923
 
872
- def ulist node
924
+ def convert_ulist node
873
925
  result = []
874
926
  id_attribute = node.id ? %( id="#{node.id}") : ''
875
927
  div_classes = ['ulist', node.style, node.role].compact
@@ -921,7 +973,7 @@ Your browser does not support the audio tag.
921
973
  result.join LF
922
974
  end
923
975
 
924
- def verse node
976
+ def convert_verse node
925
977
  id_attribute = node.id ? %( id="#{node.id}") : ''
926
978
  classes = ['verseblock', node.role].compact
927
979
  class_attribute = %( class="#{classes.join ' '}")
@@ -941,7 +993,7 @@ Your browser does not support the audio tag.
941
993
  </div>)
942
994
  end
943
995
 
944
- def video node
996
+ def convert_video node
945
997
  xml = @xml_mode
946
998
  id_attribute = node.id ? %( id="#{node.id}") : ''
947
999
  classes = ['videoblock']
@@ -964,7 +1016,7 @@ Your browser does not support the audio tag.
964
1016
  muted_param = (node.option? 'muted') ? %(#{delimiter.pop || '&amp;'}muted=1) : ''
965
1017
  %(<div#{id_attribute}#{class_attribute}>#{title_element}
966
1018
  <div class="content">
967
- <iframe#{width_attribute}#{height_attribute} src="#{asset_uri_scheme}//player.vimeo.com/video/#{node.attr 'target'}#{autoplay_param}#{loop_param}#{muted_param}#{start_anchor}" frameborder="0"#{(node.option? 'nofullscreen') ? '' : (_append_boolean_attribute 'allowfullscreen', xml)}></iframe>
1019
+ <iframe#{width_attribute}#{height_attribute} src="#{asset_uri_scheme}//player.vimeo.com/video/#{node.attr 'target'}#{autoplay_param}#{loop_param}#{muted_param}#{start_anchor}" frameborder="0"#{(node.option? 'nofullscreen') ? '' : (append_boolean_attribute 'allowfullscreen', xml)}></iframe>
968
1020
  </div>
969
1021
  </div>)
970
1022
  when 'youtube'
@@ -985,7 +1037,7 @@ Your browser does not support the audio tag.
985
1037
  fs_attribute = ''
986
1038
  else
987
1039
  fs_param = ''
988
- fs_attribute = _append_boolean_attribute 'allowfullscreen', xml
1040
+ fs_attribute = append_boolean_attribute 'allowfullscreen', xml
989
1041
  end
990
1042
  modest_param = (node.option? 'modest') ? '&amp;modestbranding=1' : ''
991
1043
  theme_param = (node.attr? 'theme') ? %(&amp;theme=#{node.attr 'theme'}) : ''
@@ -1020,7 +1072,7 @@ Your browser does not support the audio tag.
1020
1072
  time_anchor = (start_t || end_t) ? %(#t=#{start_t || ''}#{end_t ? ",#{end_t}" : ''}) : ''
1021
1073
  %(<div#{id_attribute}#{class_attribute}>#{title_element}
1022
1074
  <div class="content">
1023
- <video src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{width_attribute}#{height_attribute}#{poster_attribute}#{(node.option? 'autoplay') ? (_append_boolean_attribute 'autoplay', xml) : ''}#{(node.option? 'nocontrols') ? '' : (_append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (_append_boolean_attribute 'loop', xml) : ''}#{preload_attribute}>
1075
+ <video src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{width_attribute}#{height_attribute}#{poster_attribute}#{(node.option? 'autoplay') ? (append_boolean_attribute 'autoplay', xml) : ''}#{(node.option? 'nocontrols') ? '' : (append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (append_boolean_attribute 'loop', xml) : ''}#{preload_attribute}>
1024
1076
  Your browser does not support the video tag.
1025
1077
  </video>
1026
1078
  </div>
@@ -1028,11 +1080,11 @@ Your browser does not support the video tag.
1028
1080
  end
1029
1081
  end
1030
1082
 
1031
- def inline_anchor node
1083
+ def convert_inline_anchor node
1032
1084
  case node.type
1033
1085
  when :xref
1034
1086
  if (path = node.attributes['path'])
1035
- attrs = (_append_link_constraint_attrs node, node.role ? [%( class="#{node.role}")] : []).join
1087
+ attrs = (append_link_constraint_attrs node, node.role ? [%( class="#{node.role}")] : []).join
1036
1088
  text = node.text || path
1037
1089
  else
1038
1090
  attrs = node.role ? %( class="#{node.role}") : ''
@@ -1052,7 +1104,7 @@ Your browser does not support the video tag.
1052
1104
  attrs = node.id ? [%( id="#{node.id}")] : []
1053
1105
  attrs << %( class="#{node.role}") if node.role
1054
1106
  attrs << %( title="#{node.attr 'title'}") if node.attr? 'title'
1055
- %(<a href="#{node.target}"#{(_append_link_constraint_attrs node, attrs).join}>#{node.text}</a>)
1107
+ %(<a href="#{node.target}"#{(append_link_constraint_attrs node, attrs).join}>#{node.text}</a>)
1056
1108
  when :bibref
1057
1109
  %(<a id="#{node.id}"></a>[#{node.reftext || node.id}])
1058
1110
  else
@@ -1061,15 +1113,15 @@ Your browser does not support the video tag.
1061
1113
  end
1062
1114
  end
1063
1115
 
1064
- def inline_break node
1116
+ def convert_inline_break node
1065
1117
  %(#{node.text}<br#{@void_element_slash}>)
1066
1118
  end
1067
1119
 
1068
- def inline_button node
1120
+ def convert_inline_button node
1069
1121
  %(<b class="button">#{node.text}</b>)
1070
1122
  end
1071
1123
 
1072
- def inline_callout node
1124
+ def convert_inline_callout node
1073
1125
  if node.document.attr? 'icons', 'font'
1074
1126
  %(<i class="conum" data-value="#{node.text}"></i><b>(#{node.text})</b>)
1075
1127
  elsif node.document.attr? 'icons'
@@ -1080,7 +1132,7 @@ Your browser does not support the video tag.
1080
1132
  end
1081
1133
  end
1082
1134
 
1083
- def inline_footnote node
1135
+ def convert_inline_footnote node
1084
1136
  if (index = node.attr 'index')
1085
1137
  if node.type == :xref
1086
1138
  %(<sup class="footnoteref">[<a class="footnote" href="#_footnotedef_#{index}" title="View footnote.">#{index}</a>]</sup>)
@@ -1093,7 +1145,7 @@ Your browser does not support the video tag.
1093
1145
  end
1094
1146
  end
1095
1147
 
1096
- def inline_image node
1148
+ def convert_inline_image node
1097
1149
  if (type = node.type) == 'icon' && (node.document.attr? 'icons', 'font')
1098
1150
  class_attr_val = %(fa fa-#{node.target})
1099
1151
  { 'size' => 'fa-', 'rotate' => 'fa-rotate-', 'flip' => 'fa-flip-' }.each do |key, prefix|
@@ -1109,16 +1161,16 @@ Your browser does not support the video tag.
1109
1161
  if type != 'icon' && ((node.attr? 'format', 'svg') || (target.include? '.svg')) &&
1110
1162
  node.document.safe < SafeMode::SECURE && ((svg = (node.option? 'inline')) || (obj = (node.option? 'interactive')))
1111
1163
  if svg
1112
- img = (_read_svg_contents node, target) || %(<span class="alt">#{node.alt}</span>)
1164
+ img = (read_svg_contents node, target) || %(<span class="alt">#{node.alt}</span>)
1113
1165
  elsif obj
1114
- fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri(node.attr 'fallback')}" alt="#{_encode_attribute_value node.alt}"#{attrs}#{@void_element_slash}>) : %(<span class="alt">#{node.alt}</span>)
1166
+ fallback = (node.attr? 'fallback') ? %(<img src="#{node.image_uri(node.attr 'fallback')}" alt="#{encode_attribute_value node.alt}"#{attrs}#{@void_element_slash}>) : %(<span class="alt">#{node.alt}</span>)
1115
1167
  img = %(<object type="image/svg+xml" data="#{node.image_uri target}"#{attrs}>#{fallback}</object>)
1116
1168
  end
1117
1169
  end
1118
- img ||= %(<img src="#{type == 'icon' ? (node.icon_uri target) : (node.image_uri target)}" alt="#{_encode_attribute_value node.alt}"#{attrs}#{@void_element_slash}>)
1170
+ img ||= %(<img src="#{type == 'icon' ? (node.icon_uri target) : (node.image_uri target)}" alt="#{encode_attribute_value node.alt}"#{attrs}#{@void_element_slash}>)
1119
1171
  end
1120
1172
  if node.attr? 'link'
1121
- img = %(<a class="image" href="#{node.attr 'link'}"#{(_append_link_constraint_attrs node).join}>#{img}</a>)
1173
+ img = %(<a class="image" href="#{node.attr 'link'}"#{(append_link_constraint_attrs node).join}>#{img}</a>)
1122
1174
  end
1123
1175
  if (role = node.role)
1124
1176
  if node.attr? 'float'
@@ -1134,11 +1186,11 @@ Your browser does not support the video tag.
1134
1186
  %(<span class="#{class_attr_val}">#{img}</span>)
1135
1187
  end
1136
1188
 
1137
- def inline_indexterm node
1189
+ def convert_inline_indexterm node
1138
1190
  node.type == :visible ? node.text : ''
1139
1191
  end
1140
1192
 
1141
- def inline_kbd node
1193
+ def convert_inline_kbd node
1142
1194
  if (keys = node.attr 'keys').size == 1
1143
1195
  %(<kbd>#{keys[0]}</kbd>)
1144
1196
  else
@@ -1146,7 +1198,7 @@ Your browser does not support the video tag.
1146
1198
  end
1147
1199
  end
1148
1200
 
1149
- def inline_menu node
1201
+ def convert_inline_menu node
1150
1202
  caret = (node.document.attr? 'icons', 'font') ? '&#160;<i class="fa fa-angle-right caret"></i> ' : '&#160;<b class="caret">&#8250;</b> '
1151
1203
  submenu_joiner = %(</b>#{caret}<b class="submenu">)
1152
1204
  menu = node.attr 'menu'
@@ -1161,7 +1213,7 @@ Your browser does not support the video tag.
1161
1213
  end
1162
1214
  end
1163
1215
 
1164
- def inline_quoted node
1216
+ def convert_inline_quoted node
1165
1217
  open, close, tag = QUOTE_TAGS[node.type]
1166
1218
  if node.id
1167
1219
  class_attr = node.role ? %( class="#{node.role}") : ''
@@ -1181,13 +1233,31 @@ Your browser does not support the video tag.
1181
1233
  end
1182
1234
  end
1183
1235
 
1236
+ # NOTE expose read_svg_contents for Bespoke converter
1237
+ def read_svg_contents node, target
1238
+ if (svg = node.read_contents target, start: (node.document.attr 'imagesdir'), normalize: true, label: 'SVG')
1239
+ svg = svg.sub SvgPreambleRx, '' unless svg.start_with? '<svg'
1240
+ old_start_tag = new_start_tag = nil
1241
+ # NOTE width, height and style attributes are removed if either width or height is specified
1242
+ ['width', 'height'].each do |dim|
1243
+ if node.attr? dim
1244
+ new_start_tag = (old_start_tag = (svg.match SvgStartTagRx)[0]).gsub DimensionAttributeRx, '' unless new_start_tag
1245
+ # QUESTION should we add px since it's already the default?
1246
+ new_start_tag = %(#{new_start_tag.chop} #{dim}="#{node.attr dim}px">)
1247
+ end
1248
+ end
1249
+ svg = %(#{new_start_tag}#{svg[old_start_tag.length..-1]}) if new_start_tag
1250
+ end
1251
+ svg
1252
+ end
1253
+
1184
1254
  private
1185
1255
 
1186
- def _append_boolean_attribute name, xml
1256
+ def append_boolean_attribute name, xml
1187
1257
  xml ? %( #{name}="#{name}") : %( #{name})
1188
1258
  end
1189
1259
 
1190
- def _append_link_constraint_attrs node, attrs = []
1260
+ def append_link_constraint_attrs node, attrs = []
1191
1261
  rel = 'nofollow' if node.option? 'nofollow'
1192
1262
  if (window = node.attributes['window'])
1193
1263
  attrs << %( target="#{window}")
@@ -1198,11 +1268,11 @@ Your browser does not support the video tag.
1198
1268
  attrs
1199
1269
  end
1200
1270
 
1201
- def _encode_attribute_value val
1271
+ def encode_attribute_value val
1202
1272
  (val.include? '"') ? (val.gsub '"', '&quot;') : val
1203
1273
  end
1204
1274
 
1205
- def _generate_manname_section node
1275
+ def generate_manname_section node
1206
1276
  manname_title = node.attr 'manname-title', 'Name'
1207
1277
  if (next_section = node.sections[0]) && (next_section_title = next_section.title) == next_section_title.upcase
1208
1278
  manname_title = manname_title.upcase
@@ -1214,21 +1284,9 @@ Your browser does not support the video tag.
1214
1284
  </div>)
1215
1285
  end
1216
1286
 
1217
- def _read_svg_contents node, target
1218
- if (svg = node.read_contents target, start: (node.document.attr 'imagesdir'), normalize: true, label: 'SVG')
1219
- svg = svg.sub SvgPreambleRx, '' unless svg.start_with? '<svg'
1220
- old_start_tag = new_start_tag = nil
1221
- # NOTE width, height and style attributes are removed if either width or height is specified
1222
- ['width', 'height'].each do |dim|
1223
- if node.attr? dim
1224
- new_start_tag = (old_start_tag = (svg.match SvgStartTagRx)[0]).gsub DimensionAttributeRx, '' unless new_start_tag
1225
- # QUESTION should we add px since it's already the default?
1226
- new_start_tag = %(#{new_start_tag.chop} #{dim}="#{node.attr dim}px">)
1227
- end
1228
- end
1229
- svg = %(#{new_start_tag}#{svg[old_start_tag.length..-1]}) if new_start_tag
1230
- end
1231
- svg
1287
+ # NOTE adapt to older converters that relied on unprefixed method names
1288
+ def method_missing id, *params
1289
+ !((name = id.to_s).start_with? 'convert_') && (handles? name) ? (send %(convert_#{name}), *params) : super
1232
1290
  end
1233
1291
  end
1234
1292
  end