asciidoctor 2.0.15 → 2.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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