asciidoctor 1.5.8 → 2.0.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +11 -0
  3. data/CHANGELOG.adoc +628 -45
  4. data/LICENSE +2 -1
  5. data/README-de.adoc +28 -38
  6. data/README-fr.adoc +30 -43
  7. data/README-jp.adoc +255 -201
  8. data/README-zh_CN.adoc +40 -44
  9. data/README.adoc +170 -143
  10. data/asciidoctor.gemspec +22 -34
  11. data/bin/asciidoctor +5 -4
  12. data/data/locale/attributes-ar.adoc +4 -3
  13. data/data/locale/attributes-be.adoc +23 -0
  14. data/data/locale/attributes-bg.adoc +4 -3
  15. data/data/locale/attributes-ca.adoc +6 -5
  16. data/data/locale/attributes-cs.adoc +4 -3
  17. data/data/locale/attributes-da.adoc +6 -5
  18. data/data/locale/attributes-de.adoc +6 -5
  19. data/data/locale/attributes-en.adoc +4 -4
  20. data/data/locale/attributes-es.adoc +6 -5
  21. data/data/locale/attributes-fa.adoc +4 -3
  22. data/data/locale/attributes-fi.adoc +4 -3
  23. data/data/locale/attributes-fr.adoc +8 -7
  24. data/data/locale/attributes-hu.adoc +4 -3
  25. data/data/locale/attributes-id.adoc +4 -3
  26. data/data/locale/attributes-it.adoc +6 -5
  27. data/data/locale/attributes-ja.adoc +4 -3
  28. data/data/locale/{attributes-kr.adoc → attributes-ko.adoc} +4 -3
  29. data/data/locale/attributes-nb.adoc +4 -3
  30. data/data/locale/attributes-nl.adoc +6 -5
  31. data/data/locale/attributes-nn.adoc +4 -3
  32. data/data/locale/attributes-pl.adoc +8 -7
  33. data/data/locale/attributes-pt.adoc +6 -5
  34. data/data/locale/attributes-pt_BR.adoc +6 -5
  35. data/data/locale/attributes-ro.adoc +4 -3
  36. data/data/locale/attributes-ru.adoc +6 -5
  37. data/data/locale/attributes-sr.adoc +4 -4
  38. data/data/locale/attributes-sr_Latn.adoc +4 -4
  39. data/data/locale/attributes-sv.adoc +4 -4
  40. data/data/locale/attributes-th.adoc +23 -0
  41. data/data/locale/attributes-tr.adoc +4 -3
  42. data/data/locale/attributes-uk.adoc +6 -5
  43. data/data/locale/attributes-vi.adoc +23 -0
  44. data/data/locale/attributes-zh_CN.adoc +4 -3
  45. data/data/locale/attributes-zh_TW.adoc +4 -3
  46. data/data/reference/syntax.adoc +296 -0
  47. data/data/stylesheets/asciidoctor-default.css +120 -114
  48. data/data/stylesheets/coderay-asciidoctor.css +15 -17
  49. data/lib/asciidoctor/abstract_block.rb +146 -140
  50. data/lib/asciidoctor/abstract_node.rb +152 -170
  51. data/lib/asciidoctor/attribute_list.rb +77 -89
  52. data/lib/asciidoctor/block.rb +29 -28
  53. data/lib/asciidoctor/callouts.rb +4 -2
  54. data/lib/asciidoctor/cli/invoker.rb +20 -24
  55. data/lib/asciidoctor/cli/options.rb +107 -96
  56. data/lib/asciidoctor/cli.rb +3 -2
  57. data/lib/asciidoctor/convert.rb +199 -0
  58. data/lib/asciidoctor/converter/composite.rb +40 -48
  59. data/lib/asciidoctor/converter/docbook5.rb +627 -644
  60. data/lib/asciidoctor/converter/html5.rb +1053 -951
  61. data/lib/asciidoctor/converter/manpage.rb +581 -532
  62. data/lib/asciidoctor/converter/template.rb +232 -271
  63. data/lib/asciidoctor/converter.rb +370 -185
  64. data/lib/asciidoctor/core_ext/float/truncate.rb +20 -0
  65. data/lib/asciidoctor/core_ext/hash/merge.rb +8 -0
  66. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  67. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  68. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  69. data/lib/asciidoctor/core_ext.rb +8 -17
  70. data/lib/asciidoctor/document.rb +503 -461
  71. data/lib/asciidoctor/extensions.rb +127 -174
  72. data/lib/asciidoctor/helpers.rb +184 -107
  73. data/lib/asciidoctor/inline.rb +9 -12
  74. data/lib/asciidoctor/list.rb +11 -29
  75. data/lib/asciidoctor/load.rb +119 -0
  76. data/lib/asciidoctor/logging.rb +22 -17
  77. data/lib/asciidoctor/parser.rb +673 -719
  78. data/lib/asciidoctor/path_resolver.rb +48 -33
  79. data/lib/asciidoctor/reader.rb +383 -338
  80. data/lib/asciidoctor/rouge_ext.rb +39 -0
  81. data/lib/asciidoctor/rx.rb +723 -0
  82. data/lib/asciidoctor/section.rb +17 -16
  83. data/lib/asciidoctor/stylesheets.rb +19 -37
  84. data/lib/asciidoctor/substitutors.rb +926 -1022
  85. data/lib/asciidoctor/syntax_highlighter/coderay.rb +88 -0
  86. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +34 -0
  87. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  88. data/lib/asciidoctor/syntax_highlighter/prettify.rb +30 -0
  89. data/lib/asciidoctor/syntax_highlighter/pygments.rb +157 -0
  90. data/lib/asciidoctor/syntax_highlighter/rouge.rb +143 -0
  91. data/lib/asciidoctor/syntax_highlighter.rb +253 -0
  92. data/lib/asciidoctor/table.rb +152 -114
  93. data/lib/asciidoctor/timings.rb +7 -5
  94. data/lib/asciidoctor/version.rb +2 -1
  95. data/lib/asciidoctor/writer.rb +30 -0
  96. data/lib/asciidoctor.rb +266 -1340
  97. data/man/asciidoctor.1 +49 -47
  98. data/man/asciidoctor.adoc +54 -45
  99. metadata +50 -245
  100. data/CONTRIBUTING.adoc +0 -185
  101. data/Gemfile +0 -60
  102. data/Rakefile +0 -129
  103. data/bin/asciidoctor-safe +0 -15
  104. data/features/open_block.feature +0 -92
  105. data/features/pass_block.feature +0 -66
  106. data/features/step_definitions.rb +0 -49
  107. data/features/text_formatting.feature +0 -57
  108. data/features/xref.feature +0 -1039
  109. data/lib/asciidoctor/converter/base.rb +0 -59
  110. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  111. data/lib/asciidoctor/converter/factory.rb +0 -226
  112. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  113. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  114. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  115. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  116. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  117. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  118. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  119. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  120. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  121. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  122. data/test/api_test.rb +0 -1240
  123. data/test/attribute_list_test.rb +0 -242
  124. data/test/attributes_test.rb +0 -1623
  125. data/test/blocks_test.rb +0 -3870
  126. data/test/converter_test.rb +0 -470
  127. data/test/document_test.rb +0 -1853
  128. data/test/extensions_test.rb +0 -1560
  129. data/test/fixtures/asciidoc_index.txt +0 -521
  130. data/test/fixtures/basic-docinfo-footer.html +0 -6
  131. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  132. data/test/fixtures/basic-docinfo.html +0 -1
  133. data/test/fixtures/basic-docinfo.xml +0 -4
  134. data/test/fixtures/basic.asciidoc +0 -5
  135. data/test/fixtures/chapter-a.adoc +0 -3
  136. data/test/fixtures/child-include.adoc +0 -5
  137. data/test/fixtures/circle.svg +0 -9
  138. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  139. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  140. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  141. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  142. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  143. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  144. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  145. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  146. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  147. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  148. data/test/fixtures/docinfo-footer.html +0 -1
  149. data/test/fixtures/docinfo-footer.xml +0 -9
  150. data/test/fixtures/docinfo.html +0 -1
  151. data/test/fixtures/docinfo.xml +0 -3
  152. data/test/fixtures/doctime-localtime.adoc +0 -2
  153. data/test/fixtures/dot.gif +0 -0
  154. data/test/fixtures/encoding.asciidoc +0 -13
  155. data/test/fixtures/file-with-missing-include.adoc +0 -1
  156. data/test/fixtures/grandchild-include.adoc +0 -3
  157. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  158. data/test/fixtures/include-file.asciidoc +0 -24
  159. data/test/fixtures/include-file.jsx +0 -8
  160. data/test/fixtures/include-file.ml +0 -3
  161. data/test/fixtures/include-file.xml +0 -5
  162. data/test/fixtures/lists.adoc +0 -96
  163. data/test/fixtures/master.adoc +0 -5
  164. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  165. data/test/fixtures/other-chapters.adoc +0 -11
  166. data/test/fixtures/outer-include.adoc +0 -5
  167. data/test/fixtures/parent-include-restricted.adoc +0 -5
  168. data/test/fixtures/parent-include.adoc +0 -5
  169. data/test/fixtures/sample.asciidoc +0 -30
  170. data/test/fixtures/section-a.adoc +0 -4
  171. data/test/fixtures/stylesheets/custom.css +0 -3
  172. data/test/fixtures/subdir/index.adoc +0 -3
  173. data/test/fixtures/subdir/inner-include.adoc +0 -3
  174. data/test/fixtures/subdir/middle-include.adoc +0 -5
  175. data/test/fixtures/subs-docinfo.html +0 -2
  176. data/test/fixtures/subs.adoc +0 -6
  177. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  178. data/test/fixtures/tagged-class.rb +0 -23
  179. data/test/fixtures/tip.gif +0 -0
  180. data/test/fixtures/unclosed-tag.adoc +0 -3
  181. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  182. data/test/invoker_test.rb +0 -745
  183. data/test/links_test.rb +0 -855
  184. data/test/lists_test.rb +0 -5151
  185. data/test/logger_test.rb +0 -211
  186. data/test/manpage_test.rb +0 -660
  187. data/test/options_test.rb +0 -262
  188. data/test/paragraphs_test.rb +0 -562
  189. data/test/parser_test.rb +0 -742
  190. data/test/paths_test.rb +0 -395
  191. data/test/preamble_test.rb +0 -173
  192. data/test/reader_test.rb +0 -2161
  193. data/test/sections_test.rb +0 -3575
  194. data/test/substitutions_test.rb +0 -2066
  195. data/test/tables_test.rb +0 -2036
  196. data/test/test_helper.rb +0 -447
  197. data/test/text_test.rb +0 -309
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+ module Asciidoctor
3
+ class SyntaxHighlighter::CodeRayAdapter < SyntaxHighlighter::Base
4
+ register_for 'coderay'
5
+
6
+ def initialize *args
7
+ super
8
+ @pre_class = 'CodeRay'
9
+ @requires_stylesheet = nil
10
+ end
11
+
12
+ def highlight?
13
+ library_available?
14
+ end
15
+
16
+ def highlight node, source, lang, opts
17
+ @requires_stylesheet = true if (css_mode = opts[:css_mode]) == :class
18
+ lang = lang ? (::CodeRay::Scanners[lang = lang.to_sym] && lang rescue :text) : :text
19
+ highlighted = ::CodeRay::Duo[lang, :html,
20
+ css: css_mode,
21
+ line_numbers: (line_numbers = opts[:number_lines]),
22
+ line_number_start: opts[:start_line_number],
23
+ line_number_anchors: false,
24
+ highlight_lines: opts[:highlight_lines],
25
+ bold_every: false,
26
+ ].highlight source
27
+ if line_numbers == :table && opts[:callouts]
28
+ [highlighted, (idx = highlighted.index CodeCellStartTagCs) ? idx + CodeCellStartTagCs.length : nil]
29
+ else
30
+ highlighted
31
+ end
32
+ end
33
+
34
+ def docinfo? location
35
+ @requires_stylesheet && location == :head
36
+ end
37
+
38
+ def docinfo location, doc, opts
39
+ if opts[:linkcss]
40
+ %(<link rel="stylesheet" href="#{doc.normalize_web_path stylesheet_basename, (doc.attr 'stylesdir', ''), false}"#{opts[:self_closing_tag_slash]}>)
41
+ else
42
+ %(<style>
43
+ #{read_stylesheet}
44
+ </style>)
45
+ end
46
+ end
47
+
48
+ def write_stylesheet? doc
49
+ @requires_stylesheet
50
+ end
51
+
52
+ def write_stylesheet doc, to_dir
53
+ ::File.write (::File.join to_dir, stylesheet_basename), read_stylesheet, mode: FILE_WRITE_MODE
54
+ end
55
+
56
+ module Loader
57
+ private
58
+
59
+ def library_available?
60
+ (@@library_status ||= load_library) == :loaded ? true : nil
61
+ end
62
+
63
+ def load_library
64
+ (defined? ::CodeRay::Duo) ? :loaded : (Helpers.require_library 'coderay', true, :warn).nil? ? :unavailable : :loaded
65
+ end
66
+ end
67
+
68
+ module Styles
69
+ include Loader
70
+
71
+ def read_stylesheet
72
+ @@stylesheet_cache ||= (::File.read (::File.join Stylesheets::STYLESHEETS_DIR, stylesheet_basename), mode: FILE_READ_MODE).rstrip
73
+ end
74
+
75
+ def stylesheet_basename
76
+ 'coderay-asciidoctor.css'
77
+ end
78
+ end
79
+
80
+ extend Styles # exports static methods
81
+ include Styles # adds methods to instance
82
+ include Loader # adds methods to instance
83
+
84
+ CodeCellStartTagCs = '<td class="code"><pre>'
85
+
86
+ private_constant :CodeCellStartTagCs
87
+ end
88
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ module Asciidoctor
3
+ class SyntaxHighlighter::HighlightJsAdapter < SyntaxHighlighter::Base
4
+ register_for 'highlightjs', 'highlight.js'
5
+
6
+ def initialize *args
7
+ super
8
+ @name = @pre_class = 'highlightjs'
9
+ end
10
+
11
+ def format node, lang, opts
12
+ super node, lang, (opts.merge transform: proc {|_, code| code['class'] = %(language-#{lang || 'none'} hljs) })
13
+ end
14
+
15
+ def docinfo? location
16
+ true
17
+ end
18
+
19
+ def docinfo location, doc, opts
20
+ base_url = doc.attr 'highlightjsdir', %(#{opts[:cdn_base_url]}/highlight.js/#{HIGHLIGHT_JS_VERSION})
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
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ module Asciidoctor
3
+ class SyntaxHighlighter::HtmlPipelineAdapter < SyntaxHighlighter::Base
4
+ register_for 'html-pipeline'
5
+
6
+ def format node, lang, opts
7
+ %(<pre#{lang ? %[ lang="#{lang}"] : ''}><code>#{node.content}</code></pre>)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ module Asciidoctor
3
+ class SyntaxHighlighter::PrettifyAdapter < SyntaxHighlighter::Base
4
+ register_for 'prettify'
5
+
6
+ def initialize *args
7
+ super
8
+ @pre_class = 'prettyprint'
9
+ end
10
+
11
+ def format node, lang, opts
12
+ opts[:transform] = proc {|pre| pre['class'] += %( #{(start = node.attr 'start') ? %[linenums:#{start}] : 'linenums'}) } if node.attr? 'linenums'
13
+ super
14
+ end
15
+
16
+ def docinfo? location
17
+ true
18
+ end
19
+
20
+ def docinfo location, doc, opts
21
+ base_url = doc.attr 'prettifydir', %(#{opts[:cdn_base_url]}/prettify/r298)
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
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+ module Asciidoctor
3
+ class SyntaxHighlighter::PygmentsAdapter < SyntaxHighlighter::Base
4
+ register_for 'pygments'
5
+
6
+ def initialize *args
7
+ super
8
+ @requires_stylesheet = @style = nil
9
+ end
10
+
11
+ def highlight?
12
+ library_available?
13
+ end
14
+
15
+ def highlight node, source, lang, opts
16
+ lexer = (::Pygments::Lexer.find_by_alias lang) || (::Pygments::Lexer.find_by_mimetype 'text/plain')
17
+ @requires_stylesheet = true unless (noclasses = opts[:css_mode] != :class)
18
+ highlight_opts = {
19
+ classprefix: TOKEN_CLASS_PREFIX,
20
+ cssclass: WRAPPER_CLASS,
21
+ nobackground: true,
22
+ noclasses: noclasses,
23
+ startinline: lexer.name == 'PHP' && !(node.option? 'mixed'),
24
+ stripnl: false,
25
+ style: (@style ||= (style = opts[:style]) && (style_available? style) || DEFAULT_STYLE),
26
+ }
27
+ if (highlight_lines = opts[:highlight_lines])
28
+ highlight_opts[:hl_lines] = highlight_lines.join ' '
29
+ end
30
+ if (linenos = opts[:number_lines]) && (highlight_opts[:linenostart] = opts[:start_line_number]) && (highlight_opts[:linenos] = linenos) == :table
31
+ if (highlighted = lexer.highlight source, options: highlight_opts)
32
+ highlighted = highlighted.sub StyledLinenoColumnStartTagsRx, LinenoColumnStartTagsCs if noclasses
33
+ highlighted = highlighted.sub WrapperTagRx, PreTagCs
34
+ opts[:callouts] ? [highlighted, (idx = highlighted.index CodeCellStartTagCs) ? idx + CodeCellStartTagCs.length : nil] : highlighted
35
+ else
36
+ node.sub_source source, false # handles nil response from ::Pygments::Lexer#highlight
37
+ end
38
+ elsif (highlighted = lexer.highlight source, options: highlight_opts)
39
+ if linenos
40
+ if noclasses
41
+ highlighted = highlighted.gsub StyledLinenoSpanTagRx, LinenoSpanTagCs
42
+ elsif highlighted.include? LegacyLinenoSpanStartTagCs
43
+ highlighted = highlighted.gsub LegacyLinenoSpanTagRx, LinenoSpanTagCs
44
+ end
45
+ end
46
+ highlighted.sub WrapperTagRx, '\1'
47
+ else
48
+ node.sub_source source, false # handles nil response from ::Pygments::Lexer#highlight
49
+ end
50
+ end
51
+
52
+ def format node, lang, opts
53
+ if opts[:css_mode] != :class && (@style = (style = opts[:style]) && (style_available? style) || DEFAULT_STYLE) &&
54
+ (pre_style_attr_val = base_style @style)
55
+ opts[:transform] = proc {|pre| pre['style'] = pre_style_attr_val }
56
+ end
57
+ super
58
+ end
59
+
60
+ def docinfo? location
61
+ @requires_stylesheet && location == :head
62
+ end
63
+
64
+ def docinfo location, doc, opts
65
+ if opts[:linkcss]
66
+ %(<link rel="stylesheet" href="#{doc.normalize_web_path (stylesheet_basename @style), (doc.attr 'stylesdir', ''), false}"#{opts[:self_closing_tag_slash]}>)
67
+ else
68
+ %(<style>
69
+ #{read_stylesheet @style}
70
+ </style>)
71
+ end
72
+ end
73
+
74
+ def write_stylesheet? doc
75
+ @requires_stylesheet
76
+ end
77
+
78
+ def write_stylesheet doc, to_dir
79
+ ::File.write (::File.join to_dir, (stylesheet_basename @style)), (read_stylesheet @style), mode: FILE_WRITE_MODE
80
+ end
81
+
82
+ module Loader
83
+ private
84
+
85
+ def library_available?
86
+ (@@library_status ||= load_library) == :loaded ? true : nil
87
+ end
88
+
89
+ def load_library
90
+ (defined? ::Pygments::Lexer) ? :loaded : (Helpers.require_library 'pygments', 'pygments.rb', :warn).nil? ? :unavailable : :loaded
91
+ end
92
+ end
93
+
94
+ module Styles
95
+ include Loader
96
+
97
+ def read_stylesheet style
98
+ library_available? ? @@stylesheet_cache[style || DEFAULT_STYLE] || '/* Failed to load Pygments CSS. */' : '/* Pygments CSS disabled because Pygments is not available. */'
99
+ end
100
+
101
+ def stylesheet_basename style
102
+ %(pygments-#{style || DEFAULT_STYLE}.css)
103
+ end
104
+
105
+ private
106
+
107
+ def base_style style
108
+ library_available? ? @@base_style_cache[style || DEFAULT_STYLE] : nil
109
+ end
110
+
111
+ def style_available? style
112
+ (((@@available_styles ||= ::Pygments.styles.to_set).include? style) rescue nil) && style
113
+ end
114
+
115
+ @@base_style_cache = ::Hash.new do |cache, key|
116
+ if BaseStyleRx =~ @@stylesheet_cache[key]
117
+ @@base_style_cache = cache.merge key => (style = $1.strip)
118
+ style
119
+ end
120
+ end
121
+ @@stylesheet_cache = ::Hash.new do |cache, key|
122
+ if (stylesheet = ::Pygments.css BASE_SELECTOR, classprefix: TOKEN_CLASS_PREFIX, style: key)
123
+ stylesheet = stylesheet.slice (stylesheet.index BASE_SELECTOR), stylesheet.length unless stylesheet.start_with? BASE_SELECTOR
124
+ @@stylesheet_cache = cache.merge key => stylesheet
125
+ stylesheet
126
+ end
127
+ end
128
+
129
+ DEFAULT_STYLE = 'default'
130
+ BASE_SELECTOR = 'pre.pygments'
131
+ TOKEN_CLASS_PREFIX = 'tok-'
132
+ BaseStyleRx = /^#{BASE_SELECTOR.gsub '.', '\\.'} +\{([^}]+?)\}/
133
+
134
+ private_constant :BASE_SELECTOR, :TOKEN_CLASS_PREFIX, :BaseStyleRx
135
+ end
136
+
137
+ extend Styles # exports static methods
138
+ include Styles # adds methods to instance
139
+ include Loader # adds methods to instance
140
+
141
+ CodeCellStartTagCs = '<td class="code">'
142
+ LegacyLinenoSpanStartTagCs = '<span class="lineno">'
143
+ LegacyLinenoSpanTagRx = %r(#{LegacyLinenoSpanStartTagCs}( *\d+) ?</span>)
144
+ LinenoColumnStartTagsCs = '<td class="linenos"><div class="linenodiv"><pre>'
145
+ LinenoSpanTagCs = '<span class="linenos">\1</span>'
146
+ PreTagCs = '<pre>\1</pre>'
147
+ StyledLinenoColumnStartTagsRx = /<td><div class="linenodiv" style="[^"]+?"><pre style="[^"]+?">/
148
+ StyledLinenoSpanTagRx = %r((?<=^|<span></span>)<span style="[^"]+">( *\d+) ?</span>)
149
+ WRAPPER_CLASS = 'lineno' # doesn't appear in output; Pygments appends "table" to this value to make nested table class
150
+ # NOTE <pre> has style attribute when pygments-css=style
151
+ # NOTE <div> has trailing newline when pygments-linenums-mode=table
152
+ # NOTE initial <span></span> preserves leading blank lines
153
+ WrapperTagRx = %r(<div class="#{WRAPPER_CLASS}"><pre\b[^>]*?>(.*)</pre></div>\n*)m
154
+
155
+ private_constant :CodeCellStartTagCs, :LegacyLinenoSpanStartTagCs, :LegacyLinenoSpanTagRx, :LinenoColumnStartTagsCs, :LinenoSpanTagCs, :PreTagCs, :StyledLinenoColumnStartTagsRx, :StyledLinenoSpanTagRx, :WrapperTagRx, :WRAPPER_CLASS
156
+ end
157
+ end
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+ module Asciidoctor
3
+ class SyntaxHighlighter::RougeAdapter < SyntaxHighlighter::Base
4
+ register_for 'rouge'
5
+
6
+ def initialize *args
7
+ super
8
+ @requires_stylesheet = @style = nil
9
+ end
10
+
11
+ def highlight?
12
+ library_available?
13
+ end
14
+
15
+ def highlight node, source, lang, opts
16
+ @style ||= (style = opts[:style]) && (style_available? style) || DEFAULT_STYLE
17
+ @requires_stylesheet = true if opts[:css_mode] == :class
18
+ lexer = create_lexer node, source, lang, opts
19
+ formatter = create_formatter node, source, lang, opts
20
+ highlighted = formatter.format lexer.lex source
21
+ if opts[:number_lines] && opts[:callouts]
22
+ [highlighted, (idx = highlighted.index CodeCellStartTagCs) ? idx + CodeCellStartTagCs.length : nil]
23
+ else
24
+ highlighted
25
+ end
26
+ end
27
+
28
+ def format node, lang, opts
29
+ if (query_idx = lang && (lang.index '?'))
30
+ lang = lang.slice 0, query_idx
31
+ end
32
+ if opts[:css_mode] != :class && (@style = (style = opts[:style]) && (style_available? style) || DEFAULT_STYLE) && (pre_style_attr_val = base_style @style)
33
+ opts[:transform] = proc {|pre| pre['style'] = pre_style_attr_val }
34
+ end
35
+ super
36
+ end
37
+
38
+ def docinfo? location
39
+ @requires_stylesheet && location == :head
40
+ end
41
+
42
+ def docinfo location, doc, opts
43
+ if opts[:linkcss]
44
+ %(<link rel="stylesheet" href="#{doc.normalize_web_path (stylesheet_basename @style), (doc.attr 'stylesdir', ''), false}"#{opts[:self_closing_tag_slash]}>)
45
+ else
46
+ %(<style>
47
+ #{read_stylesheet @style}
48
+ </style>)
49
+ end
50
+ end
51
+
52
+ def write_stylesheet? doc
53
+ @requires_stylesheet
54
+ end
55
+
56
+ def write_stylesheet doc, to_dir
57
+ ::File.write (::File.join to_dir, (stylesheet_basename @style)), (read_stylesheet @style), mode: FILE_WRITE_MODE
58
+ end
59
+
60
+ def create_lexer node, source, lang, opts
61
+ if lang.include? '?'
62
+ # NOTE cgi-style options only properly supported in Rouge >= 2.1
63
+ if (lexer = ::Rouge::Lexer.find_fancy lang)
64
+ unless lexer.tag != 'php' || (node.option? 'mixed') || ((lexer_opts = lexer.options).key? 'start_inline')
65
+ lexer = lexer.class.new lexer_opts.merge 'start_inline' => true
66
+ end
67
+ end
68
+ elsif (lexer = ::Rouge::Lexer.find lang)
69
+ lexer = lexer.tag == 'php' && !(node.option? 'mixed') ? (lexer.new start_inline: true) : lexer.new
70
+ end if lang
71
+ lexer || ::Rouge::Lexers::PlainText.new
72
+ end
73
+
74
+ def create_formatter node, source, lang, opts
75
+ formatter = opts[:css_mode] == :class ?
76
+ (::Rouge::Formatters::HTML.new inline_theme: @style) :
77
+ (::Rouge::Formatters::HTMLInline.new (::Rouge::Theme.find @style).new)
78
+ if (highlight_lines = opts[:highlight_lines])
79
+ formatter = RougeExt::Formatters::HTMLLineHighlighter.new formatter, lines: highlight_lines
80
+ end
81
+ opts[:number_lines] ? (RougeExt::Formatters::HTMLTable.new formatter, start_line: opts[:start_line_number]) : formatter
82
+ end
83
+
84
+ module Loader
85
+ private
86
+
87
+ def library_available?
88
+ (@@library_status ||= load_library) == :loaded ? true : nil
89
+ end
90
+
91
+ def load_library
92
+ (defined? RougeExt) ? :loaded : (Helpers.require_library %(#{::File.dirname __dir__}/rouge_ext), 'rouge', :warn).nil? ? :unavailable : :loaded
93
+ end
94
+ end
95
+
96
+ module Styles
97
+ include Loader
98
+
99
+ def read_stylesheet style
100
+ library_available? ? @@stylesheet_cache[style || DEFAULT_STYLE] : '/* Rouge CSS disabled because Rouge is not available. */'
101
+ end
102
+
103
+ def stylesheet_basename style
104
+ %(rouge-#{style || DEFAULT_STYLE}.css)
105
+ end
106
+
107
+ private
108
+
109
+ def base_style style
110
+ library_available? ? @@base_style_cache[style || DEFAULT_STYLE] : nil
111
+ end
112
+
113
+ def style_available? style
114
+ (::Rouge::Theme.find style) && style
115
+ end
116
+
117
+ @@base_style_cache = ::Hash.new do |cache, key|
118
+ base_style = (theme = ::Rouge::Theme.find key).base_style
119
+ (val = base_style[:fg]) && ((style ||= []) << %(color: #{theme.palette val}))
120
+ (val = base_style[:bg]) && ((style ||= []) << %(background-color: #{theme.palette val}))
121
+ @@base_style_cache = cache.merge key => (resolved_base_style = style && (style.join ';'))
122
+ resolved_base_style
123
+ end
124
+ @@stylesheet_cache = ::Hash.new do |cache, key|
125
+ @@stylesheet_cache = cache.merge key => (stylesheet = ((::Rouge::Theme.find key).render scope: BASE_SELECTOR))
126
+ stylesheet
127
+ end
128
+
129
+ DEFAULT_STYLE = 'github'
130
+ BASE_SELECTOR = 'pre.rouge'
131
+
132
+ private_constant :BASE_SELECTOR
133
+ end
134
+
135
+ extend Styles # exports static methods
136
+ include Styles # adds methods to instance
137
+ include Loader # adds methods to instance
138
+
139
+ CodeCellStartTagCs = '<td class="code">'
140
+
141
+ private_constant :CodeCellStartTagCs
142
+ end
143
+ end