asciidoctor 2.0.6 → 2.0.11

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +159 -6
  3. data/LICENSE +2 -1
  4. data/README-de.adoc +5 -5
  5. data/README-fr.adoc +4 -4
  6. data/README-jp.adoc +248 -183
  7. data/README-zh_CN.adoc +6 -6
  8. data/README.adoc +17 -11
  9. data/asciidoctor.gemspec +8 -8
  10. data/data/locale/attributes-ar.adoc +4 -3
  11. data/data/locale/attributes-bg.adoc +4 -3
  12. data/data/locale/attributes-ca.adoc +6 -5
  13. data/data/locale/attributes-cs.adoc +4 -3
  14. data/data/locale/attributes-da.adoc +6 -5
  15. data/data/locale/attributes-de.adoc +4 -4
  16. data/data/locale/attributes-en.adoc +4 -4
  17. data/data/locale/attributes-es.adoc +6 -5
  18. data/data/locale/attributes-fa.adoc +4 -3
  19. data/data/locale/attributes-fi.adoc +4 -3
  20. data/data/locale/attributes-fr.adoc +6 -5
  21. data/data/locale/attributes-hu.adoc +4 -3
  22. data/data/locale/attributes-id.adoc +4 -3
  23. data/data/locale/attributes-it.adoc +4 -3
  24. data/data/locale/attributes-ja.adoc +4 -3
  25. data/data/locale/{attributes-kr.adoc → attributes-ko.adoc} +4 -3
  26. data/data/locale/attributes-nb.adoc +4 -3
  27. data/data/locale/attributes-nl.adoc +4 -3
  28. data/data/locale/attributes-nn.adoc +4 -3
  29. data/data/locale/attributes-pl.adoc +8 -7
  30. data/data/locale/attributes-pt.adoc +6 -5
  31. data/data/locale/attributes-pt_BR.adoc +6 -5
  32. data/data/locale/attributes-ro.adoc +4 -3
  33. data/data/locale/attributes-ru.adoc +6 -5
  34. data/data/locale/attributes-sr.adoc +4 -4
  35. data/data/locale/attributes-sr_Latn.adoc +4 -4
  36. data/data/locale/attributes-sv.adoc +4 -4
  37. data/data/locale/attributes-tr.adoc +4 -3
  38. data/data/locale/attributes-uk.adoc +6 -5
  39. data/data/locale/attributes-zh_CN.adoc +4 -3
  40. data/data/locale/attributes-zh_TW.adoc +4 -3
  41. data/data/stylesheets/asciidoctor-default.css +29 -26
  42. data/lib/asciidoctor.rb +94 -1098
  43. data/lib/asciidoctor/abstract_block.rb +19 -11
  44. data/lib/asciidoctor/abstract_node.rb +21 -15
  45. data/lib/asciidoctor/attribute_list.rb +59 -67
  46. data/lib/asciidoctor/cli/invoker.rb +2 -0
  47. data/lib/asciidoctor/cli/options.rb +8 -8
  48. data/lib/asciidoctor/convert.rb +198 -0
  49. data/lib/asciidoctor/converter.rb +14 -13
  50. data/lib/asciidoctor/converter/docbook5.rb +9 -25
  51. data/lib/asciidoctor/converter/html5.rb +65 -42
  52. data/lib/asciidoctor/converter/manpage.rb +13 -12
  53. data/lib/asciidoctor/converter/template.rb +6 -3
  54. data/lib/asciidoctor/document.rb +40 -48
  55. data/lib/asciidoctor/extensions.rb +3 -3
  56. data/lib/asciidoctor/helpers.rb +38 -39
  57. data/lib/asciidoctor/inline.rb +1 -1
  58. data/lib/asciidoctor/load.rb +117 -0
  59. data/lib/asciidoctor/parser.rb +29 -25
  60. data/lib/asciidoctor/path_resolver.rb +35 -25
  61. data/lib/asciidoctor/reader.rb +14 -7
  62. data/lib/asciidoctor/rx.rb +722 -0
  63. data/lib/asciidoctor/substitutors.rb +62 -40
  64. data/lib/asciidoctor/syntax_highlighter.rb +22 -8
  65. data/lib/asciidoctor/syntax_highlighter/coderay.rb +1 -1
  66. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +12 -4
  67. data/lib/asciidoctor/syntax_highlighter/prettify.rb +7 -4
  68. data/lib/asciidoctor/syntax_highlighter/pygments.rb +2 -3
  69. data/lib/asciidoctor/syntax_highlighter/rouge.rb +18 -11
  70. data/lib/asciidoctor/table.rb +49 -20
  71. data/lib/asciidoctor/version.rb +1 -1
  72. data/man/asciidoctor.1 +17 -17
  73. data/man/asciidoctor.adoc +15 -14
  74. metadata +12 -9
@@ -422,7 +422,10 @@ module Substitutors
422
422
  end
423
423
  target = $1
424
424
  attrs = parse_attributes $2, posattrs, unescape_input: true
425
- doc.register :images, [target, (attrs['imagesdir'] = doc_attrs['imagesdir'])] unless type == 'icon'
425
+ unless type == 'icon'
426
+ doc.register :images, target
427
+ attrs['imagesdir'] = doc_attrs['imagesdir']
428
+ end
426
429
  attrs['alt'] ||= (attrs['default-alt'] = Helpers.basename(target, true).tr('_-', ' '))
427
430
  Inline.new(self, :image, nil, type: type, target: target, attributes: attrs).convert
428
431
  end
@@ -539,14 +542,17 @@ module Substitutors
539
542
  end
540
543
 
541
544
  prefix, suffix = $1, ''
542
- # NOTE if $4 is set, then we're looking at a formal macro
545
+ # NOTE if $4 is set, we're looking at a formal macro (e.g., https://example.org[])
543
546
  if $4
544
547
  prefix = '' if prefix == 'link:'
545
548
  text = $4
546
549
  else
547
- # invalid macro syntax (link: prefix w/o trailing square brackets)
548
- # FIXME we probably shouldn't even get here...our regex is doing too much
549
- next $& if prefix == 'link:'
550
+ # invalid macro syntax (link: prefix w/o trailing square brackets or enclosed in double quotes)
551
+ # FIXME we probably shouldn't even get here when the link: prefix is present; the regex is doing too much
552
+ case prefix
553
+ when 'link:', ?", ?'
554
+ next $&
555
+ end
550
556
  text = ''
551
557
  case $3
552
558
  when ')'
@@ -588,7 +594,8 @@ module Substitutors
588
594
  unless text.empty?
589
595
  text = text.gsub ESC_R_SB, R_SB if text.include? R_SB
590
596
  if !doc.compat_mode && (text.include? '=')
591
- text = (attrs = (AttributeList.new text, self).parse)[1] || ''
597
+ # NOTE if an equals sign (=) is present, extract attributes from text
598
+ text, attrs = extract_attributes_from_text text, ''
592
599
  link_opts[:id] = attrs['id']
593
600
  end
594
601
 
@@ -634,7 +641,8 @@ module Substitutors
634
641
  text = text.gsub ESC_R_SB, R_SB if text.include? R_SB
635
642
  if mailto
636
643
  if !doc.compat_mode && (text.include? ',')
637
- text = (attrs = (AttributeList.new text, self).parse)[1] || ''
644
+ # NOTE if a comma (,) is present, extract attributes from text
645
+ text, attrs = extract_attributes_from_text text, ''
638
646
  link_opts[:id] = attrs['id']
639
647
  if attrs.key? 2
640
648
  if attrs.key? 3
@@ -645,7 +653,8 @@ module Substitutors
645
653
  end
646
654
  end
647
655
  elsif !doc.compat_mode && (text.include? '=')
648
- text = (attrs = (AttributeList.new text, self).parse)[1] || ''
656
+ # NOTE if an equals sign (=) is present, extract attributes from text
657
+ text, attrs = extract_attributes_from_text text, ''
649
658
  link_opts[:id] = attrs['id']
650
659
  end
651
660
 
@@ -736,8 +745,8 @@ module Substitutors
736
745
  refid = $2
737
746
  if (text = $3)
738
747
  text = text.gsub ESC_R_SB, R_SB if text.include? R_SB
739
- # NOTE if an equal sign (=) is present, parse text as attributes
740
- text = ((AttributeList.new text, self).parse_into attrs)[1] if !doc.compat_mode && (text.include? '=')
748
+ # NOTE if an equals sign (=) is present, extract attributes from text
749
+ text, attrs = extract_attributes_from_text text if !doc.compat_mode && (text.include? '=')
741
750
  end
742
751
  end
743
752
 
@@ -801,13 +810,13 @@ module Substitutors
801
810
  # handles: id (in compat mode or when natural xrefs are disabled)
802
811
  elsif doc.compat_mode || !Compliance.natural_xrefs
803
812
  refid, target = fragment, %(##{fragment})
804
- logger.info %(possible invalid reference: #{refid}) if logger.info? && doc.catalog[:refs][refid]
813
+ logger.info %(possible invalid reference: #{refid}) if logger.info? && !doc.catalog[:refs][refid]
805
814
  # handles: id
806
815
  elsif doc.catalog[:refs][fragment]
807
816
  refid, target = fragment, %(##{fragment})
808
817
  # handles: Node Title or Reference Text
809
818
  # do reverse lookup on fragment if not a known ID and resembles reftext (contains a space or uppercase char)
810
- elsif (refid = doc.resolve_id fragment) && ((fragment.include? ' ') || fragment.downcase != fragment)
819
+ elsif ((fragment.include? ' ') || fragment.downcase != fragment) && (refid = doc.resolve_id fragment)
811
820
  fragment, target = refid, %(##{refid})
812
821
  else
813
822
  refid, target = fragment, %(##{fragment})
@@ -840,19 +849,17 @@ module Substitutors
840
849
  end
841
850
 
842
851
  if id
843
- if text
852
+ if (footnote = doc.footnotes.find {|candidate| candidate.id == id })
853
+ index, text = footnote.index, footnote.text
854
+ type, target, id = :xref, id, nil
855
+ elsif text
844
856
  text = restore_passthroughs(normalize_text text, true, true)
845
857
  index = doc.counter('footnote-number')
846
858
  doc.register(:footnotes, Document::Footnote.new(index, id, text))
847
859
  type, target = :ref, nil
848
860
  else
849
- if (footnote = doc.footnotes.find {|candidate| candidate.id == id })
850
- index, text = footnote.index, footnote.text
851
- else
852
- logger.warn %(invalid footnote reference: #{id})
853
- index, text = nil, id
854
- end
855
- type, target, id = :xref, id, nil
861
+ logger.warn %(invalid footnote reference: #{id})
862
+ index, text = nil, id
856
863
  end
857
864
  elsif text
858
865
  text = restore_passthroughs(normalize_text text, true, true)
@@ -914,7 +921,7 @@ module Substitutors
914
921
  # use sub since it might be behind a line comment
915
922
  $&.sub RS, ''
916
923
  else
917
- Inline.new(self, :callout, $4 == '.' ? (autonum += 1).to_s : $4, id: @document.callouts.read_next_id, attributes: { 'guard' => $1 }).convert
924
+ Inline.new(self, :callout, $4 == '.' ? (autonum += 1).to_s : $4, id: @document.callouts.read_next_id, attributes: { 'guard' => $1 || ($3 == '--' ? ['<!--', '-->'] : nil) }).convert
918
925
  end
919
926
  end
920
927
  end
@@ -942,7 +949,7 @@ module Substitutors
942
949
  if (linenums_mode = (attr? 'linenums') ? (doc_attrs[%(#{syntax_hl_name}-linenums-mode)] || :table).to_sym : nil)
943
950
  start_line_number = 1 if (start_line_number = (attr 'start', 1).to_i) < 1
944
951
  end
945
- highlight_lines = resolve_lines_to_highlight source, (attr 'highlight') if attr? 'highlight'
952
+ highlight_lines = resolve_lines_to_highlight source, (attr 'highlight'), start_line_number if attr? 'highlight'
946
953
 
947
954
  highlighted, source_offset = syntax_hl.highlight self, source, (attr 'language'),
948
955
  callouts: callout_marks,
@@ -965,9 +972,10 @@ module Substitutors
965
972
  #
966
973
  # source - The String source.
967
974
  # spec - The lines specifier (e.g., "1-5, !2, 10" or "1..5;!2;10")
975
+ # start - The line number of the first line (optional, default: false)
968
976
  #
969
977
  # Returns an [Array] of unique, sorted line numbers.
970
- def resolve_lines_to_highlight source, spec
978
+ def resolve_lines_to_highlight source, spec, start = nil
971
979
  lines = []
972
980
  spec = spec.delete ' ' if spec.include? ' '
973
981
  ((spec.include? ',') ? (spec.split ',') : (spec.split ';')).map do |entry|
@@ -978,21 +986,22 @@ module Substitutors
978
986
  if (delim = (entry.include? '..') ? '..' : ((entry.include? '-') ? '-' : nil))
979
987
  from, delim, to = entry.partition delim
980
988
  to = (source.count LF) + 1 if to.empty? || (to = to.to_i) < 0
981
- line_nums = (from.to_i..to).to_a
982
989
  if negate
983
- lines -= line_nums
990
+ lines -= (from.to_i..to).to_a
984
991
  else
985
- lines.concat line_nums
986
- end
987
- else
988
- if negate
989
- lines.delete entry.to_i
990
- else
991
- lines << entry.to_i
992
+ lines |= (from.to_i..to).to_a
992
993
  end
994
+ elsif negate
995
+ lines.delete entry.to_i
996
+ elsif !lines.include?(line = entry.to_i)
997
+ lines << line
993
998
  end
994
999
  end
995
- lines.sort.uniq
1000
+ # If the start attribute is defined, then the lines to highlight specified by the provided spec should be relative to the start value.
1001
+ unless (shift = start ? start - 1 : 0) == 0
1002
+ lines = lines.map {|it| it - shift }
1003
+ end
1004
+ lines.sort
996
1005
  end
997
1006
 
998
1007
  # Public: Extract the passthrough text from the document for reinsertion after processing.
@@ -1318,10 +1327,23 @@ module Substitutors
1318
1327
 
1319
1328
  private
1320
1329
 
1330
+ # This method is used in cases when the attrlist can be mixed with the text of a macro.
1331
+ # If no attributes are detected aside from the first positional attribute, and the first positional
1332
+ # attribute matches the attrlist, then the original text is returned.
1333
+ def extract_attributes_from_text text, default_text = nil
1334
+ attrlist = (text.include? LF) ? (text.tr LF, ' ') : text
1335
+ if (resolved_text = (attrs = (AttributeList.new attrlist, self).parse)[1])
1336
+ # NOTE if resolved text remains unchanged, clear attributes and return unparsed text
1337
+ resolved_text == attrlist ? [text, attrs.clear] : [resolved_text, attrs]
1338
+ else
1339
+ [default_text, attrs]
1340
+ end
1341
+ end
1342
+
1321
1343
  # Internal: Extract the callout numbers from the source to prepare it for syntax highlighting.
1322
1344
  def extract_callouts source
1323
1345
  callout_marks = {}
1324
- lineno = 0
1346
+ autonum = lineno = 0
1325
1347
  last_lineno = nil
1326
1348
  callout_rx = (attr? 'line-comment') ? CalloutExtractRxMap[attr 'line-comment'] : CalloutExtractRx
1327
1349
  # extract callout marks, indexed by line number
@@ -1333,7 +1355,7 @@ module Substitutors
1333
1355
  # use sub since it might be behind a line comment
1334
1356
  $&.sub RS, ''
1335
1357
  else
1336
- (callout_marks[lineno] ||= []) << [$1, $4]
1358
+ (callout_marks[lineno] ||= []) << [$1 || ($3 == '--' ? ['<!--', '-->'] : nil), $4 == '.' ? (autonum += 1).to_s : $4]
1337
1359
  last_lineno = lineno
1338
1360
  ''
1339
1361
  end
@@ -1355,15 +1377,15 @@ module Substitutors
1355
1377
  else
1356
1378
  preamble = ''
1357
1379
  end
1358
- autonum = lineno = 0
1380
+ lineno = 0
1359
1381
  preamble + ((source.split LF, -1).map do |line|
1360
1382
  if (conums = callout_marks.delete lineno += 1)
1361
1383
  if conums.size == 1
1362
- guard, conum = conums[0]
1363
- %(#{line}#{Inline.new(self, :callout, conum == '.' ? (autonum += 1).to_s : conum, id: @document.callouts.read_next_id, attributes: { 'guard' => guard }).convert})
1384
+ guard, numeral = conums[0]
1385
+ %(#{line}#{Inline.new(self, :callout, numeral, id: @document.callouts.read_next_id, attributes: { 'guard' => guard }).convert})
1364
1386
  else
1365
- %(#{line}#{conums.map do |guard_it, conum_it|
1366
- Inline.new(self, :callout, conum_it == '.' ? (autonum += 1).to_s : conum_it, id: @document.callouts.read_next_id, attributes: { 'guard' => guard_it }).convert
1387
+ %(#{line}#{conums.map do |guard_it, numeral_it|
1388
+ Inline.new(self, :callout, numeral_it, id: @document.callouts.read_next_id, attributes: { 'guard' => guard_it }).convert
1367
1389
  end.join ' '})
1368
1390
  end
1369
1391
  else
@@ -20,19 +20,25 @@ module SyntaxHighlighter
20
20
  end
21
21
 
22
22
  # Public: Indicates whether this syntax highlighter has docinfo (i.e., markup) to insert into the output document at
23
- # the specified location.
23
+ # the specified location. Should be called by converter after main content has been converted.
24
24
  #
25
25
  # location - The Symbol representing the location slot (:head or :footer).
26
26
  #
27
27
  # Returns a [Boolean] indicating whether the docinfo method should be called for this location.
28
28
  def docinfo? location; end
29
29
 
30
- # Public: Generates docinfo markup to insert in the output document at the specified location.
30
+ # Public: Generates docinfo markup for this syntax highlighter to insert at the specified location in the output document.
31
+ # Should be called by converter after main content has been converted.
31
32
  #
32
33
  # location - The Symbol representing the location slot (:head or :footer).
34
+ # doc - The Document in which this syntax highlighter is being used.
35
+ # opts - A Hash of options that configure the syntax highlighting:
36
+ # :linkcss - A Boolean indicating whether the stylesheet should be linked instead of embedded (optional).
37
+ # :cdn_base_url - The String base URL for assets loaded from the CDN.
38
+ # :self_closing_tag_slash - The String '/' if the converter calling this method emits self-closing tags.
33
39
  #
34
40
  # Return the [String] markup to insert.
35
- def docinfo location
41
+ def docinfo location, doc, opts
36
42
  raise ::NotImplementedError, %(#{SyntaxHighlighter} subclass #{self.class} must implement the ##{__method__} method since #docinfo? returns true)
37
43
  end
38
44
 
@@ -100,15 +106,21 @@ module SyntaxHighlighter
100
106
  module Config
101
107
  # Public: Statically register the current class in the registry for the specified names.
102
108
  #
109
+ # names - one or more String or Symbol names with which to register the current class as a syntax highlighter
110
+ # implementation. Symbol arguments are coerced to Strings.
111
+ #
103
112
  # Returns nothing.
104
113
  def register_for *names
105
- SyntaxHighlighter.register self, *names
114
+ SyntaxHighlighter.register self, *(names.map {|name| name.to_s })
106
115
  end
107
116
  end
108
117
 
109
118
  module Factory
110
119
  # Public: Associates the syntax highlighter class or object with the specified names.
111
120
  #
121
+ # syntax_highlighter - the syntax highlighter implementation to register
122
+ # names - one or more String names with which to register this syntax highlighter implementation.
123
+ #
112
124
  # Returns nothing.
113
125
  def register syntax_highlighter, *names
114
126
  names.each {|name| registry[name] = syntax_highlighter }
@@ -128,7 +140,7 @@ module SyntaxHighlighter
128
140
  # name - The String name of the syntax highlighter to create.
129
141
  # backend - The String name of the backend for which this syntax highlighter is being used (default: 'html5').
130
142
  # opts - A Hash of options providing information about the context in which this syntax highlighter is used:
131
- # :doc - The Document for which this syntax highlighter was created.
143
+ # :document - The Document for which this syntax highlighter was created.
132
144
  #
133
145
  # Returns a [SyntaxHighlighter] instance for the specified name.
134
146
  def create name, backend = 'html5', opts = {}
@@ -224,9 +236,11 @@ module SyntaxHighlighter
224
236
  def format node, lang, opts
225
237
  class_attr_val = opts[:nowrap] ? %(#{@pre_class} highlight nowrap) : %(#{@pre_class} highlight)
226
238
  if (transform = opts[:transform])
227
- pre = { 'class' => class_attr_val }
228
- code = lang ? { 'data-lang' => lang } : {}
229
- transform[pre, code]
239
+ transform[(pre = { 'class' => class_attr_val }), (code = lang ? { 'data-lang' => lang } : {})]
240
+ # NOTE: make sure data-lang is the last attribute on the code tag to remain consistent with 1.5.x
241
+ if (lang = code.delete 'data-lang')
242
+ code['data-lang'] = lang
243
+ end
230
244
  %(<pre#{pre.map {|k, v| %[ #{k}="#{v}"] }.join}><code#{code.map {|k, v| %[ #{k}="#{v}"] }.join}>#{node.content}</code></pre>)
231
245
  else
232
246
  %(<pre class="#{class_attr_val}"><code#{lang ? %[ data-lang="#{lang}"] : ''}>#{node.content}</code></pre>)
@@ -32,7 +32,7 @@ class SyntaxHighlighter::CodeRayAdapter < SyntaxHighlighter::Base
32
32
  end
33
33
 
34
34
  def docinfo? location
35
- @requires_stylesheet && location == :footer
35
+ @requires_stylesheet && location == :head
36
36
  end
37
37
 
38
38
  def docinfo location, doc, opts
@@ -13,14 +13,22 @@ class SyntaxHighlighter::HighlightJsAdapter < SyntaxHighlighter::Base
13
13
  end
14
14
 
15
15
  def docinfo? location
16
- location == :footer
16
+ true
17
17
  end
18
18
 
19
19
  def docinfo location, doc, opts
20
20
  base_url = doc.attr 'highlightjsdir', %(#{opts[:cdn_base_url]}/highlight.js/#{HIGHLIGHT_JS_VERSION})
21
- %(<link rel="stylesheet" href="#{base_url}/styles/#{doc.attr 'highlightjs-theme', 'github'}.min.css"#{opts[:self_closing_tag_slash]}>
22
- <script src="#{base_url}/highlight.min.js"></script>
23
- #{(doc.attr? 'highlightjs-languages') ? ((doc.attr 'highlightjs-languages').split ',').map {|lang| %[<script src="#{base_url}/languages/#{lang.lstrip}.min.js"></script>\n] }.join : ''}<script>hljs.initHighlighting()</script>)
21
+ if location == :head
22
+ %(<link rel="stylesheet" href="#{base_url}/styles/#{doc.attr 'highlightjs-theme', 'github'}.min.css"#{opts[:self_closing_tag_slash]}>)
23
+ else # :footer
24
+ %(<script src="#{base_url}/highlight.min.js"></script>
25
+ #{(doc.attr? 'highlightjs-languages') ? ((doc.attr 'highlightjs-languages').split ',').map {|lang| %[<script src="#{base_url}/languages/#{lang.lstrip}.min.js"></script>\n] }.join : ''}<script>
26
+ if (!hljs.initHighlighting.called) {
27
+ hljs.initHighlighting.called = true
28
+ ;[].slice.call(document.querySelectorAll('pre.highlight > code')).forEach(function (el) { hljs.highlightBlock(el) })
29
+ }
30
+ </script>)
31
+ end
24
32
  end
25
33
  end
26
34
  end
@@ -14,14 +14,17 @@ class SyntaxHighlighter::PrettifyAdapter < SyntaxHighlighter::Base
14
14
  end
15
15
 
16
16
  def docinfo? location
17
- location == :footer
17
+ true
18
18
  end
19
19
 
20
20
  def docinfo location, doc, opts
21
21
  base_url = doc.attr 'prettifydir', %(#{opts[:cdn_base_url]}/prettify/r298)
22
- prettify_theme_url = ((prettify_theme = doc.attr 'prettify-theme', 'prettify').start_with? 'http://', 'https://') ? prettify_theme : %(#{base_url}/#{prettify_theme}.min.css)
23
- %(<link rel="stylesheet" href="#{prettify_theme_url}"#{opts[:self_closing_tag_slash]}>
24
- <script src="#{base_url}/run_prettify.min.js"></script>)
22
+ if location == :head
23
+ prettify_theme_url = ((prettify_theme = doc.attr 'prettify-theme', 'prettify').start_with? 'http://', 'https://') ? prettify_theme : %(#{base_url}/#{prettify_theme}.min.css)
24
+ %(<link rel="stylesheet" href="#{prettify_theme_url}"#{opts[:self_closing_tag_slash]}>)
25
+ else # :footer
26
+ %(<script src="#{base_url}/run_prettify.min.js"></script>)
27
+ end
25
28
  end
26
29
  end
27
30
  end
@@ -5,8 +5,7 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
5
5
 
6
6
  def initialize *args
7
7
  super
8
- @requires_stylesheet = nil
9
- @style = nil
8
+ @requires_stylesheet = @style = nil
10
9
  end
11
10
 
12
11
  def highlight?
@@ -53,7 +52,7 @@ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
53
52
  end
54
53
 
55
54
  def docinfo? location
56
- @requires_stylesheet && location == :footer
55
+ @requires_stylesheet && location == :head
57
56
  end
58
57
 
59
58
  def docinfo location, doc, opts
@@ -5,8 +5,7 @@ class SyntaxHighlighter::RougeAdapter < SyntaxHighlighter::Base
5
5
 
6
6
  def initialize *args
7
7
  super
8
- @requires_stylesheet = nil
9
- @style = nil
8
+ @requires_stylesheet = @style = nil
10
9
  end
11
10
 
12
11
  def highlight?
@@ -14,14 +13,23 @@ class SyntaxHighlighter::RougeAdapter < SyntaxHighlighter::Base
14
13
  end
15
14
 
16
15
  def highlight node, source, lang, opts
17
- lexer = (::Rouge::Lexer.find_fancy lang) || ::Rouge::Lexers::PlainText
18
- lexer_opts = lexer.tag == 'php' && !(node.option? 'mixed') ? { start_inline: true } : {}
16
+ if lang.include? '?'
17
+ # NOTE cgi-style options only properly supported in Rouge >= 2.1
18
+ if (lexer = ::Rouge::Lexer.find_fancy lang)
19
+ unless lexer.tag != 'php' || (node.option? 'mixed') || ((lexer_opts = lexer.options).key? 'start_inline')
20
+ lexer = lexer.class.new lexer_opts.merge 'start_inline' => true
21
+ end
22
+ end
23
+ elsif (lexer = ::Rouge::Lexer.find lang)
24
+ lexer = lexer.tag == 'php' && !(node.option? 'mixed') ? (lexer.new start_inline: true) : lexer.new
25
+ end if lang
26
+ lexer ||= ::Rouge::Lexers::PlainText.new
19
27
  @style ||= (style = opts[:style]) && (style_available? style) || DEFAULT_STYLE
20
28
  if opts[:css_mode] == :class
21
29
  @requires_stylesheet = true
22
- formatter = ::Rouge::Formatters::HTML.new @style
30
+ formatter = ::Rouge::Formatters::HTML.new inline_theme: @style
23
31
  else
24
- formatter = ::Rouge::Formatters::HTMLInline.new @style
32
+ formatter = ::Rouge::Formatters::HTMLInline.new (::Rouge::Theme.find @style).new
25
33
  end
26
34
  if (highlight_lines = opts[:highlight_lines])
27
35
  formatter = RougeExt::Formatters::HTMLLineHighlighter.new formatter, lines: highlight_lines
@@ -29,25 +37,24 @@ class SyntaxHighlighter::RougeAdapter < SyntaxHighlighter::Base
29
37
  if opts[:number_lines]
30
38
  formatter = RougeExt::Formatters::HTMLTable.new formatter, start_line: opts[:start_line_number]
31
39
  if opts[:callouts]
32
- return [(highlighted = formatter.format lexer.lex source, lexer_opts), (idx = highlighted.index CodeCellStartTagCs) ? idx + CodeCellStartTagCs.length : nil]
40
+ return [(highlighted = formatter.format lexer.lex source), (idx = highlighted.index CodeCellStartTagCs) ? idx + CodeCellStartTagCs.length : nil]
33
41
  end
34
42
  end
35
- formatter.format lexer.lex source, lexer_opts
43
+ formatter.format lexer.lex source
36
44
  end
37
45
 
38
46
  def format node, lang, opts
39
47
  if (query_idx = lang && (lang.index '?'))
40
48
  lang = lang.slice 0, query_idx
41
49
  end
42
- if opts[:css_mode] != :class && (@style = (style = opts[:style]) && (style_available? style) || DEFAULT_STYLE) &&
43
- (pre_style_attr_val = base_style @style)
50
+ if opts[:css_mode] != :class && (@style = (style = opts[:style]) && (style_available? style) || DEFAULT_STYLE) && (pre_style_attr_val = base_style @style)
44
51
  opts[:transform] = proc {|pre| pre['style'] = pre_style_attr_val }
45
52
  end
46
53
  super
47
54
  end
48
55
 
49
56
  def docinfo? location
50
- @requires_stylesheet && location == :footer
57
+ @requires_stylesheet && location == :head
51
58
  end
52
59
 
53
60
  def docinfo location, doc, opts