asciidoctor 2.0.15 → 2.0.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +38 -2
  3. data/LICENSE +1 -1
  4. data/README-de.adoc +3 -3
  5. data/README-fr.adoc +3 -3
  6. data/README-jp.adoc +3 -3
  7. data/README-zh_CN.adoc +3 -3
  8. data/README.adoc +2 -2
  9. data/asciidoctor.gemspec +1 -8
  10. data/data/locale/attributes-th.adoc +23 -0
  11. data/data/locale/attributes-vi.adoc +23 -0
  12. data/data/stylesheets/asciidoctor-default.css +50 -48
  13. data/lib/asciidoctor.rb +7 -7
  14. data/lib/asciidoctor/abstract_block.rb +4 -4
  15. data/lib/asciidoctor/abstract_node.rb +9 -8
  16. data/lib/asciidoctor/block.rb +6 -6
  17. data/lib/asciidoctor/cli/invoker.rb +0 -1
  18. data/lib/asciidoctor/cli/options.rb +22 -22
  19. data/lib/asciidoctor/convert.rb +1 -0
  20. data/lib/asciidoctor/converter.rb +5 -3
  21. data/lib/asciidoctor/converter/docbook5.rb +20 -22
  22. data/lib/asciidoctor/converter/html5.rb +70 -60
  23. data/lib/asciidoctor/converter/manpage.rb +61 -52
  24. data/lib/asciidoctor/converter/template.rb +11 -12
  25. data/lib/asciidoctor/document.rb +22 -37
  26. data/lib/asciidoctor/extensions.rb +10 -10
  27. data/lib/asciidoctor/list.rb +2 -6
  28. data/lib/asciidoctor/load.rb +10 -9
  29. data/lib/asciidoctor/logging.rb +10 -8
  30. data/lib/asciidoctor/parser.rb +122 -141
  31. data/lib/asciidoctor/path_resolver.rb +3 -3
  32. data/lib/asciidoctor/reader.rb +67 -68
  33. data/lib/asciidoctor/rx.rb +2 -1
  34. data/lib/asciidoctor/substitutors.rb +97 -99
  35. data/lib/asciidoctor/syntax_highlighter.rb +8 -11
  36. data/lib/asciidoctor/syntax_highlighter/coderay.rb +2 -1
  37. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +1 -1
  38. data/lib/asciidoctor/syntax_highlighter/pygments.rb +2 -1
  39. data/lib/asciidoctor/syntax_highlighter/rouge.rb +2 -1
  40. data/lib/asciidoctor/table.rb +17 -19
  41. data/lib/asciidoctor/timings.rb +3 -3
  42. data/lib/asciidoctor/version.rb +1 -1
  43. data/man/asciidoctor.1 +8 -9
  44. data/man/asciidoctor.adoc +7 -6
  45. metadata +7 -61
data/lib/asciidoctor.rb CHANGED
@@ -53,12 +53,12 @@ module Asciidoctor
53
53
  module SafeMode
54
54
  # A safe mode level that disables any of the security features enforced
55
55
  # by Asciidoctor (Ruby is still subject to its own restrictions).
56
- UNSAFE = 0;
56
+ UNSAFE = 0
57
57
 
58
58
  # A safe mode level that closely parallels safe mode in AsciiDoc. This value
59
59
  # prevents access to files which reside outside of the parent directory of
60
60
  # the source file and disables any macro other than the include::[] directive.
61
- SAFE = 1;
61
+ SAFE = 1
62
62
 
63
63
  # A safe mode level that disallows the document from setting attributes
64
64
  # that would affect the conversion of the document, in addition to all the
@@ -66,19 +66,19 @@ module Asciidoctor
66
66
  # changing the backend or source-highlighter using an attribute defined
67
67
  # in the source document header. This is the most fundamental level of
68
68
  # security for server deployments (hence the name).
69
- SERVER = 10;
69
+ SERVER = 10
70
70
 
71
71
  # A safe mode level that disallows the document from attempting to read
72
72
  # files from the file system and including the contents of them into the
73
73
  # document, in additional to all the security features of SafeMode::SERVER.
74
74
  # For instance, this level disallows use of the include::[] directive and the
75
75
  # embedding of binary content (data uri), stylesheets and JavaScripts
76
- # referenced by the document.(Asciidoctor and trusted extensions may still
76
+ # referenced by the document. (Asciidoctor and trusted extensions may still
77
77
  # be allowed to embed trusted content into the document).
78
78
  #
79
79
  # Since Asciidoctor is aiming for wide adoption, this level is the default
80
80
  # and is recommended for server deployments.
81
- SECURE = 20;
81
+ SECURE = 20
82
82
 
83
83
  # A planned safe mode level that disallows the use of passthrough macros and
84
84
  # prevents the document from setting any known attributes, in addition to all
@@ -86,9 +86,9 @@ module Asciidoctor
86
86
  #
87
87
  # Please note that this level is not currently implemented (and therefore not
88
88
  # enforced)!
89
- #PARANOID = 100;
89
+ #PARANOID = 100
90
90
 
91
- @names_by_value = {}.tap {|accum| (constants false).each {|sym| accum[const_get sym, false] = sym.to_s.downcase } }
91
+ @names_by_value = (constants false).map {|sym| [(const_get sym), sym.to_s.downcase] }.sort {|(a), (b)| a <=> b }.to_h
92
92
 
93
93
  def self.value_for_name name
94
94
  const_get name.upcase, false
@@ -90,7 +90,7 @@ class AbstractBlock < AbstractNode
90
90
  #
91
91
  # context - the context Symbol context to assign to this block
92
92
  #
93
- # Returns the new context Symbol assigned to this block
93
+ # Returns the specified Symbol context
94
94
  def context= context
95
95
  @node_name = (@context = context).to_s
96
96
  end
@@ -296,7 +296,7 @@ class AbstractBlock < AbstractNode
296
296
 
297
297
  # Public: Set the String block title.
298
298
  #
299
- # Returns the new String title assigned to this Block
299
+ # Returns the specified String title
300
300
  def title= val
301
301
  @converted_title = nil
302
302
  @title = val
@@ -480,7 +480,7 @@ class AbstractBlock < AbstractNode
480
480
  @header.find_by_internal selector, result, &block
481
481
  end
482
482
  @blocks.each do |b|
483
- next if (context_selector == :section && b.context != :section) # optimization
483
+ next if context_selector == :section && b.context != :section # optimization
484
484
  b.find_by_internal selector, result, &block
485
485
  end
486
486
  end
@@ -505,7 +505,7 @@ class AbstractBlock < AbstractNode
505
505
  end
506
506
  else
507
507
  @blocks.each do |b|
508
- next if (context_selector == :section && b.context != :section) # optimization
508
+ next if context_selector == :section && b.context != :section # optimization
509
509
  b.find_by_internal selector, result, &block
510
510
  end
511
511
  end
@@ -4,7 +4,8 @@ module Asciidoctor
4
4
  # node of AsciiDoc content. The state and methods on this class are common to
5
5
  # all content segments in an AsciiDoc document.
6
6
  class AbstractNode
7
- include Substitutors, Logging
7
+ include Logging
8
+ include Substitutors
8
9
 
9
10
  # Public: Get the Hash of attributes for this node
10
11
  attr_reader :attributes
@@ -65,7 +66,7 @@ class AbstractNode
65
66
  #
66
67
  # parent - The Block to set as the parent of this Block
67
68
  #
68
- # Returns the value of the parent argument
69
+ # Returns the the specified Block parent
69
70
  def parent= parent
70
71
  @parent, @document = parent, parent.document
71
72
  end
@@ -155,7 +156,7 @@ class AbstractNode
155
156
  #
156
157
  # name - the String name of the option
157
158
  #
158
- # Returns Nothing
159
+ # Returns nothing
159
160
  def set_option name
160
161
  @attributes[%(#{name}-option)] = ''
161
162
  nil
@@ -220,7 +221,7 @@ class AbstractNode
220
221
  #
221
222
  # names - A single role name, a space-separated String of role names, or an Array of role names
222
223
  #
223
- # Returns the value of the names argument
224
+ # Returns the specified String role name or Array of role names
224
225
  def role= names
225
226
  @attributes['role'] = (::Array === names) ? (names.join ' ') : names
226
227
  end
@@ -462,8 +463,8 @@ class AbstractNode
462
463
  start = doc.base_dir
463
464
  end
464
465
  else
465
- start = doc.base_dir unless start
466
- jail = doc.base_dir unless jail
466
+ start ||= doc.base_dir
467
+ jail ||= doc.base_dir
467
468
  end
468
469
  doc.path_resolver.system_path target, start, jail, opts
469
470
  end
@@ -542,8 +543,8 @@ class AbstractNode
542
543
  rescue
543
544
  logger.warn %(could not retrieve contents of #{opts[:label] || 'asset'} at URI: #{target}) if opts.fetch :warn_on_failure, true
544
545
  end
545
- else
546
- logger.warn %(cannot retrieve contents of #{opts[:label] || 'asset'} at URI: #{target} (allow-uri-read attribute not enabled)) if opts.fetch :warn_on_failure, true
546
+ elsif opts.fetch :warn_on_failure, true
547
+ logger.warn %(cannot retrieve contents of #{opts[:label] || 'asset'} at URI: #{target} (allow-uri-read attribute not enabled))
547
548
  end
548
549
  else
549
550
  target = normalize_system_path target, opts[:start], nil, target_name: (opts[:label] || 'asset')
@@ -54,21 +54,21 @@ class Block < AbstractBlock
54
54
  # FIXME feels funky; we have to be defensive to get commit_subs to honor override
55
55
  # FIXME does not resolve substitution groups inside Array (e.g., [:normal])
56
56
  if (subs = opts[:subs])
57
- # e.g., subs: :defult
57
+ case subs
58
+ # e.g., subs: :default
58
59
  # subs attribute is honored; falls back to opts[:default_subs], then built-in defaults based on context
59
- if subs == :default
60
+ when :default
60
61
  @default_subs = opts[:default_subs]
61
62
  # e.g., subs: [:quotes]
62
63
  # subs attribute is not honored
63
- elsif ::Array === subs
64
+ when ::Array
64
65
  @default_subs = subs.drop 0
65
66
  @attributes.delete 'subs'
66
67
  # e.g., subs: :normal or subs: 'normal'
67
68
  # subs attribute is not honored
68
69
  else
69
70
  @default_subs = nil
70
- # interpolation is the fastest way to dup subs as a string
71
- @attributes['subs'] = %(#{subs})
71
+ @attributes['subs'] = subs.to_s
72
72
  end
73
73
  # resolve the subs eagerly only if subs option is specified
74
74
  # QUESTION should we skip subsequent calls to commit_subs?
@@ -123,7 +123,7 @@ class Block < AbstractBlock
123
123
  result.join LF
124
124
  end
125
125
  else
126
- logger.warn %(Unknown content model '#{@content_model}' for block: #{to_s}) unless @content_model == :empty
126
+ logger.warn %(Unknown content model '#{@content_model}' for block: #{self}) unless @content_model == :empty
127
127
  nil
128
128
  end
129
129
  end
@@ -88,7 +88,6 @@ module Asciidoctor
88
88
  end
89
89
 
90
90
  if outfile == '-'
91
- # NOTE set_encoding returns nil on JRuby 9.1
92
91
  (tofile = @out) || ((tofile = $stdout).set_encoding UTF_8)
93
92
  elsif outfile
94
93
  opts[:mkdirs] = true
@@ -47,12 +47,12 @@ module Asciidoctor
47
47
  EOS
48
48
 
49
49
  opts.on('-b', '--backend BACKEND', 'set backend output format: [html5, xhtml5, docbook5, manpage] (default: html5)',
50
- 'additional backends are supported via extended converters (e.g., pdf, epub3)') do |backend|
50
+ 'additional backends are supported via extended converters (e.g., pdf, epub3)') do |backend|
51
51
  self[:attributes]['backend'] = backend
52
52
  end
53
53
  opts.on('-d', '--doctype DOCTYPE', ['article', 'book', 'manpage', 'inline'],
54
- 'document type to use when converting document: [article, book, manpage, inline] (default: article)') do |doc_type|
55
- self[:attributes]['doctype'] = doc_type
54
+ 'document type to use when converting document: [article, book, manpage, inline] (default: article)') do |doctype|
55
+ self[:attributes]['doctype'] = doctype
56
56
  end
57
57
  opts.on('-e', '--embedded', 'suppress enclosing document structure and output an embedded document (default: false)') do
58
58
  self[:standalone] = false
@@ -61,14 +61,14 @@ module Asciidoctor
61
61
  self[:output_file] = output_file
62
62
  end
63
63
  opts.on('--safe',
64
- 'set safe mode level to safe (default: unsafe)',
65
- 'enables include directives, but prevents access to ancestor paths of source file',
66
- 'provided for compatibility with the asciidoc command') do
64
+ 'set safe mode level to safe (default: unsafe)',
65
+ 'enables include directives, but prevents access to ancestor paths of source file',
66
+ 'provided for compatibility with the asciidoc command') do
67
67
  self[:safe] = SafeMode::SAFE
68
68
  end
69
69
  opts.on('-S', '--safe-mode SAFE_MODE', (safe_mode_names = SafeMode.names),
70
- %(set safe mode level explicitly: [#{safe_mode_names.join ', '}] (default: unsafe)),
71
- 'disables potentially dangerous macros in source files, such as include::[]') do |name|
70
+ %(set safe mode level explicitly: [#{safe_mode_names.join ', '}] (default: unsafe)),
71
+ 'disables potentially dangerous macros in source files, such as include::[]') do |name|
72
72
  self[:safe] = SafeMode.value_for_name name
73
73
  end
74
74
  opts.on('-s', '--no-header-footer', 'suppress enclosing document structure and output an embedded document (default: false)') do
@@ -78,19 +78,19 @@ module Asciidoctor
78
78
  self[:attributes]['sectnums'] = ''
79
79
  end
80
80
  opts.on('--eruby ERUBY', ['erb', 'erubi', 'erubis'],
81
- 'specify eRuby implementation to use when rendering custom ERB templates: [erb, erubi, erubis] (default: erb)') do |eruby|
81
+ 'specify eRuby implementation to use when rendering custom ERB templates: [erb, erubi, erubis] (default: erb)') do |eruby|
82
82
  self[:eruby] = eruby
83
83
  end
84
84
  opts.on('-a', '--attribute name[=value]', 'a document attribute to set in the form of name, name!, or name=value pair',
85
- 'this attribute takes precedence over the same attribute defined in the source document',
86
- 'unless either the name or value ends in @ (i.e., name@=value or name=value@)') do |attr|
85
+ 'this attribute takes precedence over the same attribute defined in the source document',
86
+ 'unless either the name or value ends in @ (i.e., name@=value or name=value@)') do |attr|
87
87
  next if (attr = attr.rstrip).empty? || attr == '='
88
88
  attr = attr.encode UTF_8 unless attr.encoding == UTF_8
89
89
  name, _, val = attr.partition '='
90
90
  self[:attributes][name] = val
91
91
  end
92
92
  opts.on('-T', '--template-dir DIR', 'a directory containing custom converter templates that override the built-in converter (requires tilt gem)',
93
- 'may be specified multiple times') do |template_dir|
93
+ 'may be specified multiple times') do |template_dir|
94
94
  if self[:template_dirs].nil?
95
95
  self[:template_dirs] = [template_dir]
96
96
  elsif ::Array === self[:template_dirs]
@@ -121,21 +121,21 @@ module Asciidoctor
121
121
  end
122
122
  opts.on('--failure-level LEVEL', %w(warning WARNING error ERROR info INFO), 'set minimum logging level that triggers non-zero exit code: [WARN, ERROR, INFO] (default: FATAL)') do |level|
123
123
  level = 'WARN' if (level = level.upcase) == 'WARNING'
124
- self[:failure_level] = ::Logger::Severity.const_get level, false
124
+ self[:failure_level] = ::Logger::Severity.const_get level
125
125
  end
126
- opts.on('-q', '--quiet', 'silence application log messages and script warnings (default: false)') do |verbose|
126
+ opts.on('-q', '--quiet', 'silence application log messages and script warnings (default: false)') do
127
127
  self[:verbose] = 0
128
128
  end
129
- opts.on('--trace', 'include backtrace information when reporting errors (default: false)') do |trace|
129
+ opts.on('--trace', 'include backtrace information when reporting errors (default: false)') do
130
130
  self[:trace] = true
131
131
  end
132
- opts.on('-v', '--verbose', 'directs application messages logged at DEBUG or INFO level to STDERR (default: false)') do |verbose|
132
+ opts.on('-v', '--verbose', 'directs application messages logged at DEBUG or INFO level to STDERR (default: false)') do
133
133
  self[:verbose] = 2
134
134
  end
135
- opts.on('-w', '--warnings', 'turn on script warnings (default: false)') do |warnings|
135
+ opts.on('-w', '--warnings', 'turn on script warnings (default: false)') do
136
136
  self[:warnings] = true
137
137
  end
138
- opts.on('-t', '--timings', 'print timings report (default: false)') do |timing|
138
+ opts.on('-t', '--timings', 'print timings report (default: false)') do
139
139
  self[:timings] = true
140
140
  end
141
141
  opts.on_tail('-h', '--help [TOPIC]', 'print a help message',
@@ -161,7 +161,7 @@ module Asciidoctor
161
161
  elsif ::File.exist? (manpage_path = (::File.join ROOT_DIR, 'man', 'asciidoctor.1'))
162
162
  $stdout.puts ::File.read manpage_path
163
163
  else
164
- manpage_path = `man -w asciidoctor`.chop rescue ''
164
+ manpage_path = %x(man -w asciidoctor).chop rescue ''
165
165
  if manpage_path.empty?
166
166
  $stderr.puts 'asciidoctor: FAILED: manual page not found; try `man asciidoctor`'
167
167
  return 1
@@ -249,7 +249,7 @@ module Asciidoctor
249
249
 
250
250
  self[:input_files] = infiles
251
251
 
252
- self.delete :attributes if self[:attributes].empty?
252
+ delete :attributes if self[:attributes].empty?
253
253
 
254
254
  if self[:template_dirs]
255
255
  begin
@@ -290,11 +290,11 @@ module Asciidoctor
290
290
  rescue ::OptionParser::MissingArgument
291
291
  $stderr.puts %(asciidoctor: option #{$!.message})
292
292
  $stdout.puts opts_parser
293
- return 1
293
+ 1
294
294
  rescue ::OptionParser::InvalidOption, ::OptionParser::InvalidArgument
295
295
  $stderr.puts %(asciidoctor: #{$!.message})
296
296
  $stdout.puts opts_parser
297
- return 1
297
+ 1
298
298
  ensure
299
299
  $VERBOSE = old_verbose
300
300
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Asciidoctor
2
3
  class << self
3
4
  # Public: Parse the AsciiDoc source input into an Asciidoctor::Document and
@@ -366,15 +366,17 @@ module Converter
366
366
  # into - The Class into which the {Converter} module is being included.
367
367
  #
368
368
  # Returns nothing.
369
- private_class_method def self.included into
369
+ def self.included into
370
370
  into.send :include, BackendTraits
371
371
  into.extend Config
372
- end || :included
372
+ end
373
+ private_class_method :included # use separate declaration for Ruby 2.0.x
373
374
 
374
375
  # An abstract base class for defining converters that can be used to convert {AbstractNode} objects in a parsed
375
376
  # AsciiDoc document to a backend format such as HTML or DocBook.
376
377
  class Base
377
- include Converter, Logging
378
+ include Logging
379
+ include Converter
378
380
 
379
381
  # Public: Converts an {AbstractNode} by delegating to a method that matches the transform value.
380
382
  #
@@ -7,9 +7,9 @@ class Converter::DocBook5Converter < Converter::Base
7
7
 
8
8
  # default represents variablelist
9
9
  (DLIST_TAGS = {
10
- 'qanda' => { list: 'qandaset', entry: 'qandaentry', label: 'question', term: 'simpara', item: 'answer' },
11
- 'glossary' => { list: nil, entry: 'glossentry', term: 'glossterm', item: 'glossdef' },
12
- }).default = { list: 'variablelist', entry: 'varlistentry', term: 'term', item: 'listitem' }
10
+ 'qanda' => { list: 'qandaset', entry: 'qandaentry', label: 'question', term: 'simpara', item: 'answer' },
11
+ 'glossary' => { list: nil, entry: 'glossentry', term: 'glossterm', item: 'glossdef' },
12
+ }).default = { list: 'variablelist', entry: 'varlistentry', term: 'term', item: 'listitem' }
13
13
 
14
14
  (QUOTE_TAGS = {
15
15
  monospaced: ['<literal>', '</literal>'],
@@ -25,7 +25,7 @@ class Converter::DocBook5Converter < Converter::Base
25
25
  MANPAGE_SECTION_TAGS = { 'section' => 'refsection', 'synopsis' => 'refsynopsisdiv' }
26
26
  TABLE_PI_NAMES = ['dbhtml', 'dbfo', 'dblatex']
27
27
 
28
- CopyrightRx = /^(#{CC_ANY}+?)(?: ((?:\d{4}\-)?\d{4}))?$/
28
+ CopyrightRx = /^(#{CC_ANY}+?)(?: ((?:\d{4}-)?\d{4}))?$/
29
29
  ImageMacroRx = /^image::?(\S|\S#{CC_ANY}*?\S)\[(#{CC_ANY}+)?\]$/
30
30
 
31
31
  def initialize backend, opts = {}
@@ -302,13 +302,13 @@ class Converter::DocBook5Converter < Converter::Base
302
302
  </abstract>)
303
303
  end
304
304
  when 'partintro'
305
- unless node.level == 0 && node.parent.context == :section && node.document.doctype == 'book'
306
- logger.error 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
307
- ''
308
- else
305
+ if node.level == 0 && node.parent.context == :section && node.document.doctype == 'book'
309
306
  %(<partintro#{common_attributes node.id, node.role, node.reftext}>
310
307
  #{title_tag node}#{enclose_content node}
311
308
  </partintro>)
309
+ else
310
+ logger.error 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
311
+ ''
312
312
  end
313
313
  else
314
314
  reftext = node.reftext if (id = node.id)
@@ -378,19 +378,19 @@ class Converter::DocBook5Converter < Converter::Base
378
378
  frame = 'topbot' if (frame = node.attr 'frame', 'all', 'table-frame') == 'ends'
379
379
  grid = node.attr 'grid', nil, 'table-grid'
380
380
  result << %(<#{tag_name = node.title? ? 'table' : 'informaltable'}#{common_attributes node.id, node.role, node.reftext}#{pgwide_attribute} frame="#{frame}" rowsep="#{['none', 'cols'].include?(grid) ? 0 : 1}" colsep="#{['none', 'rows'].include?(grid) ? 0 : 1}"#{(node.attr? 'orientation', 'landscape', 'table-orientation') ? ' orient="land"' : ''}>)
381
- if (node.option? 'unbreakable')
381
+ if node.option? 'unbreakable'
382
382
  result << '<?dbfo keep-together="always"?>'
383
- elsif (node.option? 'breakable')
383
+ elsif node.option? 'breakable'
384
384
  result << '<?dbfo keep-together="auto"?>'
385
385
  end
386
386
  result << %(<title>#{node.title}</title>) if tag_name == 'table'
387
- col_width_key = if (width = (node.attr? 'width') ? (node.attr 'width') : nil)
387
+ if (width = (node.attr? 'width') ? (node.attr 'width') : nil)
388
388
  TABLE_PI_NAMES.each do |pi_name|
389
389
  result << %(<?#{pi_name} table-width="#{width}"?>)
390
390
  end
391
- 'colabswidth'
391
+ col_width_key = 'colabswidth'
392
392
  else
393
- 'colpcwidth'
393
+ col_width_key = 'colpcwidth'
394
394
  end
395
395
  result << %(<tgroup cols="#{node.attr 'colcount'}">)
396
396
  node.columns.each do |col|
@@ -543,9 +543,8 @@ class Converter::DocBook5Converter < Converter::Base
543
543
  %(<indexterm>
544
544
  <primary>#{node.text}</primary>#{rel}
545
545
  </indexterm>#{node.text})
546
- else
547
- if (numterms = (terms = node.attr 'terms').size) > 2
548
- %(<indexterm>
546
+ elsif (numterms = (terms = node.attr 'terms').size) > 2
547
+ %(<indexterm>
549
548
  <primary>#{terms[0]}</primary><secondary>#{terms[1]}</secondary><tertiary>#{terms[2]}</tertiary>#{rel}
550
549
  </indexterm>#{(node.document.option? 'indexterm-promotion') ? %[
551
550
  <indexterm>
@@ -554,18 +553,17 @@ class Converter::DocBook5Converter < Converter::Base
554
553
  <indexterm>
555
554
  <primary>#{terms[2]}</primary>
556
555
  </indexterm>] : ''})
557
- elsif numterms > 1
558
- %(<indexterm>
556
+ elsif numterms > 1
557
+ %(<indexterm>
559
558
  <primary>#{terms[0]}</primary><secondary>#{terms[1]}</secondary>#{rel}
560
- </indexterm>#{(node.document.option? 'indexterm-promotion') ? %[
559
+ </indexterm>#{(node.document.option? 'indexterm-promotion') ? %[
561
560
  <indexterm>
562
561
  <primary>#{terms[1]}</primary>
563
562
  </indexterm>] : ''})
564
- else
565
- %(<indexterm>
563
+ else
564
+ %(<indexterm>
566
565
  <primary>#{terms[0]}</primary>#{rel}
567
566
  </indexterm>)
568
- end
569
567
  end
570
568
  end
571
569
 
@@ -21,7 +21,7 @@ class Converter::Html5Converter < Converter::Base
21
21
  #latexmath: INLINE_MATH_DELIMITERS[:latexmath] + [false],
22
22
  }).default = ['', '']
23
23
 
24
- DropAnchorRx = /<(?:a\b[^>]*|\/a)>/
24
+ DropAnchorRx = %r(<(?:a\b[^>]*|/a)>)
25
25
  StemBreakRx = / *\\\n(?:\\?\n)*|\n\n+/
26
26
  if RUBY_ENGINE == 'opal'
27
27
  # NOTE In JavaScript, ^ matches the start of the string when the m flag is not set
@@ -48,44 +48,45 @@ class Converter::Html5Converter < Converter::Base
48
48
  end
49
49
 
50
50
  def convert node, transform = node.node_name, opts = nil
51
- if transform == 'inline_quoted'; return convert_inline_quoted node
52
- elsif transform == 'paragraph'; return convert_paragraph node
53
- elsif transform == 'inline_anchor'; return convert_inline_anchor node
54
- elsif transform == 'section'; return convert_section node
55
- elsif transform == 'listing'; return convert_listing node
56
- elsif transform == 'literal'; return convert_literal node
57
- elsif transform == 'ulist'; return convert_ulist node
58
- elsif transform == 'olist'; return convert_olist node
59
- elsif transform == 'dlist'; return convert_dlist node
60
- elsif transform == 'admonition'; return convert_admonition node
61
- elsif transform == 'colist'; return convert_colist node
62
- elsif transform == 'embedded'; return convert_embedded node
63
- elsif transform == 'example'; return convert_example node
64
- elsif transform == 'floating_title'; return convert_floating_title node
65
- elsif transform == 'image'; return convert_image node
66
- elsif transform == 'inline_break'; return convert_inline_break node
67
- elsif transform == 'inline_button'; return convert_inline_button node
68
- elsif transform == 'inline_callout'; return convert_inline_callout node
69
- elsif transform == 'inline_footnote'; return convert_inline_footnote node
70
- elsif transform == 'inline_image'; return convert_inline_image node
71
- elsif transform == 'inline_indexterm'; return convert_inline_indexterm node
72
- elsif transform == 'inline_kbd'; return convert_inline_kbd node
73
- elsif transform == 'inline_menu'; return convert_inline_menu node
74
- elsif transform == 'open'; return convert_open node
75
- elsif transform == 'page_break'; return convert_page_break node
76
- elsif transform == 'preamble'; return convert_preamble node
77
- elsif transform == 'quote'; return convert_quote node
78
- elsif transform == 'sidebar'; return convert_sidebar node
79
- elsif transform == 'stem'; return convert_stem node
80
- elsif transform == 'table'; return convert_table node
81
- elsif transform == 'thematic_break'; return convert_thematic_break node
82
- elsif transform == 'verse'; return convert_verse node
83
- elsif transform == 'video'; return convert_video node
84
- elsif transform == 'document'; return convert_document node
85
- elsif transform == 'toc'; return convert_toc node
86
- elsif transform == 'pass'; return convert_pass node
87
- elsif transform == 'audio'; return convert_audio node
88
- else; return super
51
+ case transform
52
+ when 'inline_quoted' then convert_inline_quoted node
53
+ when 'paragraph' then convert_paragraph node
54
+ when 'inline_anchor' then convert_inline_anchor node
55
+ when 'section' then convert_section node
56
+ when 'listing' then convert_listing node
57
+ when 'literal' then convert_literal node
58
+ when 'ulist' then convert_ulist node
59
+ when 'olist' then convert_olist node
60
+ when 'dlist' then convert_dlist node
61
+ when 'admonition' then convert_admonition node
62
+ when 'colist' then convert_colist node
63
+ when 'embedded' then convert_embedded node
64
+ when 'example' then convert_example node
65
+ when 'floating_title' then convert_floating_title node
66
+ when 'image' then convert_image node
67
+ when 'inline_break' then convert_inline_break node
68
+ when 'inline_button' then convert_inline_button node
69
+ when 'inline_callout' then convert_inline_callout node
70
+ when 'inline_footnote' then convert_inline_footnote node
71
+ when 'inline_image' then convert_inline_image node
72
+ when 'inline_indexterm' then convert_inline_indexterm node
73
+ when 'inline_kbd' then convert_inline_kbd node
74
+ when 'inline_menu' then convert_inline_menu node
75
+ when 'open' then convert_open node
76
+ when 'page_break' then convert_page_break node
77
+ when 'preamble' then convert_preamble node
78
+ when 'quote' then convert_quote node
79
+ when 'sidebar' then convert_sidebar node
80
+ when 'stem' then convert_stem node
81
+ when 'table' then convert_table node
82
+ when 'thematic_break' then convert_thematic_break node
83
+ when 'verse' then convert_verse node
84
+ when 'video' then convert_video node
85
+ when 'document' then convert_document node
86
+ when 'toc' then convert_toc node
87
+ when 'pass' then convert_pass node
88
+ when 'audio' then convert_audio node
89
+ else; super
89
90
  end
90
91
  end
91
92
 
@@ -350,9 +351,10 @@ MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
350
351
  stitle = section.captioned_title
351
352
  elsif section.numbered && slevel <= sectnumlevels
352
353
  if slevel < 2 && node.document.doctype == 'book'
353
- if section.sectname == 'chapter'
354
+ case section.sectname
355
+ when 'chapter'
354
356
  stitle = %(#{(signifier = node.document.attributes['chapter-signifier']) ? "#{signifier} " : ''}#{section.sectnum} #{section.title})
355
- elsif section.sectname == 'part'
357
+ when 'part'
356
358
  stitle = %(#{(signifier = node.document.attributes['part-signifier']) ? "#{signifier} " : ''}#{section.sectnum nil, ':'} #{section.title})
357
359
  else
358
360
  stitle = %(#{section.sectnum} #{section.title})
@@ -383,9 +385,10 @@ MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
383
385
  title = node.captioned_title
384
386
  elsif node.numbered && level <= (doc_attrs['sectnumlevels'] || 3).to_i
385
387
  if level < 2 && node.document.doctype == 'book'
386
- if node.sectname == 'chapter'
388
+ case node.sectname
389
+ when 'chapter'
387
390
  title = %(#{(signifier = doc_attrs['chapter-signifier']) ? "#{signifier} " : ''}#{node.sectnum} #{node.title})
388
- elsif node.sectname == 'part'
391
+ when 'part'
389
392
  title = %(#{(signifier = doc_attrs['part-signifier']) ? "#{signifier} " : ''}#{node.sectnum nil, ':'} #{node.title})
390
393
  else
391
394
  title = %(#{node.sectnum} #{node.title})
@@ -513,16 +516,16 @@ Your browser does not support the audio tag.
513
516
  result = []
514
517
  id_attribute = node.id ? %( id="#{node.id}") : ''
515
518
 
516
- classes = case node.style
519
+ case node.style
517
520
  when 'qanda'
518
- ['qlist', 'qanda', node.role]
521
+ classes = ['qlist', 'qanda', node.role]
519
522
  when 'horizontal'
520
- ['hdlist', node.role]
523
+ classes = ['hdlist', node.role]
521
524
  else
522
- ['dlist', node.style, node.role]
523
- end.compact
525
+ classes = ['dlist', node.style, node.role]
526
+ end
524
527
 
525
- class_attribute = %( class="#{classes.join ' '}")
528
+ class_attribute = %( class="#{classes.compact.join ' '}")
526
529
 
527
530
  result << %(<div#{id_attribute}#{class_attribute}>)
528
531
  result << %(<div class="title">#{node.title}</div>) if node.title?
@@ -578,12 +581,11 @@ Your browser does not support the audio tag.
578
581
  terms.each do |dt|
579
582
  result << %(<dt#{dt_style_attribute}>#{dt.text}</dt>)
580
583
  end
581
- if dd
582
- result << '<dd>'
583
- result << %(<p>#{dd.text}</p>) if dd.text?
584
- result << dd.content if dd.blocks?
585
- result << '</dd>'
586
- end
584
+ next unless dd
585
+ result << '<dd>'
586
+ result << %(<p>#{dd.text}</p>) if dd.text?
587
+ result << dd.content if dd.blocks?
588
+ result << '</dd>'
587
589
  end
588
590
  result << '</dl>'
589
591
  end
@@ -759,8 +761,8 @@ Your browser does not support the audio tag.
759
761
  logger.error 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
760
762
  ''
761
763
  else
762
- id_attr = node.id ? %( id="#{node.id}") : ''
763
- title_el = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
764
+ id_attr = node.id ? %( id="#{node.id}") : ''
765
+ title_el = node.title? ? %(<div class="title">#{node.title}</div>\n) : ''
764
766
  %(<div#{id_attr} class="openblock#{style && style != 'open' ? " #{style}" : ''}#{(role = node.role) ? " #{role}" : ''}">
765
767
  #{title_el}<div class="content">
766
768
  #{node.content}
@@ -1189,7 +1191,11 @@ Your browser does not support the video tag.
1189
1191
  img = %([#{node.alt}])
1190
1192
  else
1191
1193
  target = node.target
1192
- attrs = ['width', 'height', 'title'].map {|name| (node.attr? name) ? %( #{name}="#{node.attr name}") : '' }.join
1194
+ attrs = []
1195
+ attrs << %( width="#{node.attr 'width'}") if node.attr? 'width'
1196
+ attrs << %( height="#{node.attr 'height'}") if node.attr? 'height'
1197
+ attrs << %( title="#{node.attr 'title'}") if node.attr? 'title'
1198
+ attrs = attrs.empty? ? '' : attrs.join
1193
1199
  if type != 'icon' && ((node.attr? 'format', 'svg') || (target.include? '.svg')) &&
1194
1200
  node.document.safe < SafeMode::SECURE && ((svg = (node.option? 'inline')) || (obj = (node.option? 'interactive')))
1195
1201
  if svg
@@ -1325,8 +1331,12 @@ Your browser does not support the video tag.
1325
1331
  end
1326
1332
 
1327
1333
  # NOTE adapt to older converters that relied on unprefixed method names
1328
- def method_missing id, *params
1329
- !((name = id.to_s).start_with? 'convert_') && (handles? name) ? (send %(convert_#{name}), *params) : super
1334
+ def method_missing id, *args
1335
+ !((name = id.to_s).start_with? 'convert_') && (handles? name) ? (send %(convert_#{name}), *args) : super
1336
+ end
1337
+
1338
+ def respond_to_missing? id, *options
1339
+ !((name = id.to_s).start_with? 'convert_') && (handles? name)
1330
1340
  end
1331
1341
  end
1332
1342
  end