asciidoctor 1.5.8 → 2.0.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +11 -0
- data/CHANGELOG.adoc +628 -45
- data/LICENSE +2 -1
- data/README-de.adoc +28 -38
- data/README-fr.adoc +30 -43
- data/README-jp.adoc +255 -201
- data/README-zh_CN.adoc +40 -44
- data/README.adoc +170 -143
- data/asciidoctor.gemspec +22 -34
- data/bin/asciidoctor +5 -4
- data/data/locale/attributes-ar.adoc +4 -3
- data/data/locale/attributes-be.adoc +23 -0
- data/data/locale/attributes-bg.adoc +4 -3
- data/data/locale/attributes-ca.adoc +6 -5
- data/data/locale/attributes-cs.adoc +4 -3
- data/data/locale/attributes-da.adoc +6 -5
- data/data/locale/attributes-de.adoc +6 -5
- data/data/locale/attributes-en.adoc +4 -4
- data/data/locale/attributes-es.adoc +6 -5
- data/data/locale/attributes-fa.adoc +4 -3
- data/data/locale/attributes-fi.adoc +4 -3
- data/data/locale/attributes-fr.adoc +8 -7
- data/data/locale/attributes-hu.adoc +4 -3
- data/data/locale/attributes-id.adoc +4 -3
- data/data/locale/attributes-it.adoc +6 -5
- data/data/locale/attributes-ja.adoc +4 -3
- data/data/locale/{attributes-kr.adoc → attributes-ko.adoc} +4 -3
- data/data/locale/attributes-nb.adoc +4 -3
- data/data/locale/attributes-nl.adoc +6 -5
- data/data/locale/attributes-nn.adoc +4 -3
- data/data/locale/attributes-pl.adoc +8 -7
- data/data/locale/attributes-pt.adoc +6 -5
- data/data/locale/attributes-pt_BR.adoc +6 -5
- data/data/locale/attributes-ro.adoc +4 -3
- data/data/locale/attributes-ru.adoc +6 -5
- data/data/locale/attributes-sr.adoc +4 -4
- data/data/locale/attributes-sr_Latn.adoc +4 -4
- data/data/locale/attributes-sv.adoc +4 -4
- data/data/locale/attributes-th.adoc +23 -0
- data/data/locale/attributes-tr.adoc +4 -3
- data/data/locale/attributes-uk.adoc +6 -5
- data/data/locale/attributes-vi.adoc +23 -0
- data/data/locale/attributes-zh_CN.adoc +4 -3
- data/data/locale/attributes-zh_TW.adoc +4 -3
- data/data/reference/syntax.adoc +296 -0
- data/data/stylesheets/asciidoctor-default.css +120 -114
- data/data/stylesheets/coderay-asciidoctor.css +15 -17
- data/lib/asciidoctor/abstract_block.rb +146 -140
- data/lib/asciidoctor/abstract_node.rb +152 -170
- data/lib/asciidoctor/attribute_list.rb +77 -89
- data/lib/asciidoctor/block.rb +29 -28
- data/lib/asciidoctor/callouts.rb +4 -2
- data/lib/asciidoctor/cli/invoker.rb +20 -24
- data/lib/asciidoctor/cli/options.rb +107 -96
- data/lib/asciidoctor/cli.rb +3 -2
- data/lib/asciidoctor/convert.rb +199 -0
- data/lib/asciidoctor/converter/composite.rb +40 -48
- data/lib/asciidoctor/converter/docbook5.rb +627 -644
- data/lib/asciidoctor/converter/html5.rb +1053 -951
- data/lib/asciidoctor/converter/manpage.rb +581 -532
- data/lib/asciidoctor/converter/template.rb +232 -271
- data/lib/asciidoctor/converter.rb +370 -185
- data/lib/asciidoctor/core_ext/float/truncate.rb +20 -0
- data/lib/asciidoctor/core_ext/hash/merge.rb +8 -0
- data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
- data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
- data/lib/asciidoctor/core_ext.rb +8 -17
- data/lib/asciidoctor/document.rb +503 -461
- data/lib/asciidoctor/extensions.rb +127 -174
- data/lib/asciidoctor/helpers.rb +184 -107
- data/lib/asciidoctor/inline.rb +9 -12
- data/lib/asciidoctor/list.rb +11 -29
- data/lib/asciidoctor/load.rb +119 -0
- data/lib/asciidoctor/logging.rb +22 -17
- data/lib/asciidoctor/parser.rb +673 -719
- data/lib/asciidoctor/path_resolver.rb +48 -33
- data/lib/asciidoctor/reader.rb +383 -338
- data/lib/asciidoctor/rouge_ext.rb +39 -0
- data/lib/asciidoctor/rx.rb +723 -0
- data/lib/asciidoctor/section.rb +17 -16
- data/lib/asciidoctor/stylesheets.rb +19 -37
- data/lib/asciidoctor/substitutors.rb +926 -1022
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +88 -0
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +34 -0
- data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
- data/lib/asciidoctor/syntax_highlighter/prettify.rb +30 -0
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +157 -0
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +143 -0
- data/lib/asciidoctor/syntax_highlighter.rb +253 -0
- data/lib/asciidoctor/table.rb +152 -114
- data/lib/asciidoctor/timings.rb +7 -5
- data/lib/asciidoctor/version.rb +2 -1
- data/lib/asciidoctor/writer.rb +30 -0
- data/lib/asciidoctor.rb +266 -1340
- data/man/asciidoctor.1 +49 -47
- data/man/asciidoctor.adoc +54 -45
- metadata +50 -245
- data/CONTRIBUTING.adoc +0 -185
- data/Gemfile +0 -60
- data/Rakefile +0 -129
- data/bin/asciidoctor-safe +0 -15
- data/features/open_block.feature +0 -92
- data/features/pass_block.feature +0 -66
- data/features/step_definitions.rb +0 -49
- data/features/text_formatting.feature +0 -57
- data/features/xref.feature +0 -1039
- data/lib/asciidoctor/converter/base.rb +0 -59
- data/lib/asciidoctor/converter/docbook45.rb +0 -93
- data/lib/asciidoctor/converter/factory.rb +0 -226
- data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
- data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
- data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
- data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
- data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
- data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
- data/test/api_test.rb +0 -1240
- data/test/attribute_list_test.rb +0 -242
- data/test/attributes_test.rb +0 -1623
- data/test/blocks_test.rb +0 -3870
- data/test/converter_test.rb +0 -470
- data/test/document_test.rb +0 -1853
- data/test/extensions_test.rb +0 -1560
- data/test/fixtures/asciidoc_index.txt +0 -521
- data/test/fixtures/basic-docinfo-footer.html +0 -6
- data/test/fixtures/basic-docinfo-footer.xml +0 -8
- data/test/fixtures/basic-docinfo.html +0 -1
- data/test/fixtures/basic-docinfo.xml +0 -4
- data/test/fixtures/basic.asciidoc +0 -5
- data/test/fixtures/chapter-a.adoc +0 -3
- data/test/fixtures/child-include.adoc +0 -5
- data/test/fixtures/circle.svg +0 -9
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
- data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
- data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
- data/test/fixtures/docinfo-footer.html +0 -1
- data/test/fixtures/docinfo-footer.xml +0 -9
- data/test/fixtures/docinfo.html +0 -1
- data/test/fixtures/docinfo.xml +0 -3
- data/test/fixtures/doctime-localtime.adoc +0 -2
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +0 -13
- data/test/fixtures/file-with-missing-include.adoc +0 -1
- data/test/fixtures/grandchild-include.adoc +0 -3
- data/test/fixtures/hello-asciidoctor.pdf +0 -69
- data/test/fixtures/include-file.asciidoc +0 -24
- data/test/fixtures/include-file.jsx +0 -8
- data/test/fixtures/include-file.ml +0 -3
- data/test/fixtures/include-file.xml +0 -5
- data/test/fixtures/lists.adoc +0 -96
- data/test/fixtures/master.adoc +0 -5
- data/test/fixtures/mismatched-end-tag.adoc +0 -7
- data/test/fixtures/other-chapters.adoc +0 -11
- data/test/fixtures/outer-include.adoc +0 -5
- data/test/fixtures/parent-include-restricted.adoc +0 -5
- data/test/fixtures/parent-include.adoc +0 -5
- data/test/fixtures/sample.asciidoc +0 -30
- data/test/fixtures/section-a.adoc +0 -4
- data/test/fixtures/stylesheets/custom.css +0 -3
- data/test/fixtures/subdir/index.adoc +0 -3
- data/test/fixtures/subdir/inner-include.adoc +0 -3
- data/test/fixtures/subdir/middle-include.adoc +0 -5
- data/test/fixtures/subs-docinfo.html +0 -2
- data/test/fixtures/subs.adoc +0 -6
- data/test/fixtures/tagged-class-enclosed.rb +0 -25
- data/test/fixtures/tagged-class.rb +0 -23
- data/test/fixtures/tip.gif +0 -0
- data/test/fixtures/unclosed-tag.adoc +0 -3
- data/test/fixtures/unexpected-end-tag.adoc +0 -4
- data/test/invoker_test.rb +0 -745
- data/test/links_test.rb +0 -855
- data/test/lists_test.rb +0 -5151
- data/test/logger_test.rb +0 -211
- data/test/manpage_test.rb +0 -660
- data/test/options_test.rb +0 -262
- data/test/paragraphs_test.rb +0 -562
- data/test/parser_test.rb +0 -742
- data/test/paths_test.rb +0 -395
- data/test/preamble_test.rb +0 -173
- data/test/reader_test.rb +0 -2161
- data/test/sections_test.rb +0 -3575
- data/test/substitutions_test.rb +0 -2066
- data/test/tables_test.rb +0 -2036
- data/test/test_helper.rb +0 -447
- 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
|