asciidoctor-reducer 1.0.0.alpha.8 → 1.0.0.alpha.9
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.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +26 -0
- data/README.adoc +66 -3
- data/bin/asciidoctor-reducer +2 -7
- data/lib/asciidoctor/reducer/api.rb +17 -14
- data/lib/asciidoctor/reducer/cli.rb +109 -105
- data/lib/asciidoctor/reducer/conditional_directive_tracker.rb +1 -1
- data/lib/asciidoctor/reducer/extensions.rb +12 -9
- data/lib/asciidoctor/reducer/include_directive_tracker.rb +27 -21
- data/lib/asciidoctor/reducer/include_mapper/extension.rb +16 -0
- data/lib/asciidoctor/reducer/include_mapper.rb +8 -0
- data/lib/asciidoctor/reducer/preprocessor.rb +2 -2
- data/lib/asciidoctor/reducer/tree_processor.rb +1 -1
- data/lib/asciidoctor/reducer/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80723a5097c54761a2bee3b3ea88f827c88614b7a5572a6b5f1b10cb7af60c8c
|
4
|
+
data.tar.gz: d6f23a15e6dae8db02f5810d22018f537af9d6e67ac8362dbc2fe3155417df2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db4173fd2899008fec759e9d76f2732a7f5f7ca0a284f5c66a93040b9fca81dba22cf151e77e86b2b73c535545cec4b3a54c88407324514811260832b8ed1c7d
|
7
|
+
data.tar.gz: ec7a7d27cb1b87dcb0772af642f185002f7348e0a540c40bf3a6e98334d7be0b088b8b00312ca10dd5470cdaff60007e70c2d27708d97c4677c7a3302694473e
|
data/CHANGELOG.adoc
CHANGED
@@ -4,6 +4,32 @@
|
|
4
4
|
This document provides a high-level view of the changes to the Asciidoctor Reducer by release.
|
5
5
|
For a detailed view of what has changed, refer to the {url-repo}/commits/main[commit history] on GitHub.
|
6
6
|
|
7
|
+
== 1.0.0.alpha.9 (2022-04-21) - @mojavelinux
|
8
|
+
|
9
|
+
=== Added
|
10
|
+
|
11
|
+
* Add `Asciidoctor::Reducer::IncludeMapper` auxiliary extension, required by `asciidoctor/reducer/include_mapper/extension` (#26)
|
12
|
+
* Register `Asciidoctor::Reducer::IncludeMapper` extension when `asciidoctor/reducer/include_mapper` is required (#26)
|
13
|
+
* Add `Asciidoctor::Reducer::Extensions.key` method that returns key for registering extension group
|
14
|
+
* Update help text to note that the `-a` and `-r` CLI options may be specified multiple times
|
15
|
+
* Automate the release process
|
16
|
+
|
17
|
+
=== Changed
|
18
|
+
|
19
|
+
* Rename x_include_replacements attr on reader to include_replacements since it's public
|
20
|
+
* Don't pass `:to` option to `Asciidoctor.load_file`
|
21
|
+
* Make `Asciidoctor::Reducer::Cli` a module instead of a class
|
22
|
+
|
23
|
+
=== Fixed
|
24
|
+
|
25
|
+
* Replace remote include with link if `allow-uri-read` attribute is not set
|
26
|
+
* Don't raise error if `Asciidoctor::Reducer::Extensions.unregister` is called when extensions are not registered globally
|
27
|
+
* Ensure output is written to file with universal newlines (\n) on Windows
|
28
|
+
|
29
|
+
=== Details
|
30
|
+
|
31
|
+
{url-repo}/releases/tag/v1.0.0.alpha.9[git tag] | {url-repo}/compare/v1.0.0.alpha.8\...v1.0.0.alpha.9[full diff]
|
32
|
+
|
7
33
|
== 1.0.0.alpha.8 (2022-02-23) - @mojavelinux
|
8
34
|
|
9
35
|
=== Added
|
data/README.adoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= {project-name}
|
2
2
|
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>
|
3
|
-
v1.0.0.alpha.
|
3
|
+
v1.0.0.alpha.9, 2022-04-21
|
4
4
|
:idprefix:
|
5
5
|
:idseparator: -
|
6
6
|
ifndef::env-github[:icons: font]
|
@@ -16,8 +16,8 @@ endif::[]
|
|
16
16
|
:url-rvm: https://rvm.io
|
17
17
|
:url-repo: https://github.com/asciidoctor/{project-handle}
|
18
18
|
|
19
|
-
{project-name} is a tool that reduces
|
20
|
-
The tool also applies preprocessor conditionals (unless the option to preserve them is specified), leaving behind only the
|
19
|
+
{project-name} is a tool that reduces an AsciiDoc document that contains includes to a single AsciiDoc document by expanding any includes reachable from the parent document.
|
20
|
+
The tool also applies preprocessor conditionals (unless the option to preserve them is specified), leaving behind only the selected lines.
|
21
21
|
If the document does not contain any preprocessor directives, the tool returns the original source.
|
22
22
|
|
23
23
|
== Prerequisites
|
@@ -197,6 +197,69 @@ This call will cause extensions that run during the load phase to be invoked aga
|
|
197
197
|
An extension can check for this secondary load by checking for the `:reduced` option in the `Document#options` hash.
|
198
198
|
If this option is set (the value of which will be `true`), then Asciidoctor is loading the reduced document.
|
199
199
|
|
200
|
+
== Include Mapper (Experimental)
|
201
|
+
|
202
|
+
One of the challenges of reducing a document is that interdocument xrefs that rely on the includes being registered in the document catalog no longer work.
|
203
|
+
That's because when the reduced document is converted, it has no includes and thus all interdocument xrefs are colocated in the same source file.
|
204
|
+
To work around this shortcoming, {project-name} provides a utility extension named the include mapper that will carry over the includes in the document catalog to the reduced document so they can be imported during conversion.
|
205
|
+
|
206
|
+
CAUTION: The include mapper is experimental and thus subject to change.
|
207
|
+
|
208
|
+
To use the include mapper when using the CLI to reduce the document, require it using the `-r` option as follows:
|
209
|
+
|
210
|
+
$ asciidoctor-reducer -r asciidoctor/reducer/include_mapper -o input-reduced.adoc input.adoc
|
211
|
+
|
212
|
+
To use the include mapper when converting the reduced document, again require it using the `-r` option as follows:
|
213
|
+
|
214
|
+
$ asciidoctor -r asciidoctor/reducer/include_mapper input-reduced.adoc
|
215
|
+
|
216
|
+
To use the include mapper when using the API, first require the extension:
|
217
|
+
|
218
|
+
[,ruby]
|
219
|
+
----
|
220
|
+
require 'asciidocotor/reducer/include_mapper/extension'
|
221
|
+
----
|
222
|
+
|
223
|
+
You then need to register the extension when reducing the document:
|
224
|
+
|
225
|
+
[,ruby]
|
226
|
+
----
|
227
|
+
Asciidoctor::Reducer.reduce_file 'sample.adoc', to: 'sample-reduced.adoc', extensions: proc {
|
228
|
+
next if document.options[:reduced]
|
229
|
+
tree_processor Asciidoctor::Reducer::IncludeMapper
|
230
|
+
}
|
231
|
+
----
|
232
|
+
|
233
|
+
Then register it again when converting the reduced document:
|
234
|
+
|
235
|
+
[,ruby]
|
236
|
+
----
|
237
|
+
Asciidoctor.convert_file 'sample-reduced.adoc', safe: :safe, extensions: proc {
|
238
|
+
tree_processor Asciidoctor::Reducer::IncludeMapper
|
239
|
+
}
|
240
|
+
----
|
241
|
+
|
242
|
+
You can also register the extension globally:
|
243
|
+
|
244
|
+
[,ruby]
|
245
|
+
----
|
246
|
+
require 'asciidocotor/reducer/include_mapper'
|
247
|
+
----
|
248
|
+
|
249
|
+
In this case, you don't have to pass it to the API explicitly.
|
250
|
+
|
251
|
+
=== How it Works
|
252
|
+
|
253
|
+
The include mapper works by adding a magic comment to the bottom of the reduced file.
|
254
|
+
Here's an example of that comment:
|
255
|
+
|
256
|
+
[,asciidoc]
|
257
|
+
----
|
258
|
+
//# includes=chapters/chapter-a,chapters/chapter-b
|
259
|
+
----
|
260
|
+
|
261
|
+
When a document that contains the magic comment is converted, the include mapper reads the comma-separated paths in the value and loads them into the includes table of the document catalog.
|
262
|
+
|
200
263
|
== Development
|
201
264
|
|
202
265
|
Follow the instructions below to learn how to help develop the project or test-drive the development version.
|
data/bin/asciidoctor-reducer
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
asciidoctor_reducer_cli = File.
|
5
|
-
|
6
|
-
require asciidoctor_reducer_cli
|
7
|
-
else
|
8
|
-
require 'asciidoctor/reducer/cli'
|
9
|
-
end
|
10
|
-
|
4
|
+
asciidoctor_reducer_cli = File.join (File.dirname __dir__), 'lib/asciidoctor/reducer/cli.rb'
|
5
|
+
require (File.file? asciidoctor_reducer_cli) ? asciidoctor_reducer_cli : 'asciidoctor/reducer/cli'
|
11
6
|
exit Asciidoctor::Reducer::Cli.run
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
autoload :Pathname, 'pathname'
|
4
4
|
require_relative 'extensions'
|
5
5
|
|
6
6
|
module Asciidoctor::Reducer
|
@@ -8,8 +8,12 @@ module Asciidoctor::Reducer
|
|
8
8
|
|
9
9
|
class << self
|
10
10
|
def reduce input, opts = {}
|
11
|
-
opts = opts
|
12
|
-
opts[:
|
11
|
+
opts = opts&.merge || {}
|
12
|
+
if (extension_registry = Extensions.prepare_registry opts[:extension_registry] || opts[:extensions])
|
13
|
+
opts[:extension_registry] = extension_registry
|
14
|
+
end
|
15
|
+
opts[:safe] ||= :safe
|
16
|
+
to = opts.delete :to
|
13
17
|
case input
|
14
18
|
when ::File
|
15
19
|
doc = ::Asciidoctor.load_file input, opts
|
@@ -18,7 +22,7 @@ module Asciidoctor::Reducer
|
|
18
22
|
else
|
19
23
|
doc = ::Asciidoctor.load input, opts
|
20
24
|
end
|
21
|
-
write doc,
|
25
|
+
write doc, to
|
22
26
|
end
|
23
27
|
|
24
28
|
def reduce_file input_file, opts = {}
|
@@ -28,16 +32,15 @@ module Asciidoctor::Reducer
|
|
28
32
|
private
|
29
33
|
|
30
34
|
def write doc, to
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
35
|
+
return doc unless to && to != '/dev/null'
|
36
|
+
output = doc.source
|
37
|
+
return output if to == ::String
|
38
|
+
output += LF unless output.empty?
|
39
|
+
if ::Pathname === to || (!(to.respond_to? :write) && (to = ::Pathname.new to.to_s))
|
40
|
+
to.dirname.mkpath
|
41
|
+
to.write output, encoding: UTF_8, newline: :universal
|
42
|
+
else
|
43
|
+
to.write output
|
41
44
|
end
|
42
45
|
doc
|
43
46
|
end
|
@@ -4,134 +4,138 @@ require_relative 'api'
|
|
4
4
|
autoload :OptionParser, 'optparse'
|
5
5
|
|
6
6
|
module Asciidoctor::Reducer
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
7
|
+
module Cli
|
8
|
+
class << self
|
9
|
+
def parse args
|
10
|
+
options = { attributes: {}, log_level: LOG_LEVELS['warn'], safe: :unsafe }
|
11
|
+
|
12
|
+
opt_parser = ::OptionParser.new do |opts|
|
13
|
+
opts.program_name = 'asciidoctor-reducer'
|
14
|
+
opts.banner = <<~END
|
15
|
+
Usage: #{opts.program_name} [OPTION]... FILE
|
16
|
+
|
17
|
+
Reduces a composite AsciiDoc document containing includes and conditionals to a single AsciiDoc document.
|
18
|
+
|
19
|
+
END
|
20
|
+
|
21
|
+
opts.on '-a KEY[=VALUE]', '--attribute=KEY[=VALUE]',
|
22
|
+
'set a document attribute in the AsciiDoc document: [key, key!, key=value]',
|
23
|
+
'may be specified multiple times' do |attr|
|
24
|
+
key, val = attr.split '=', 2
|
25
|
+
val ||= ''
|
26
|
+
options[:attributes][key] = val
|
27
|
+
end
|
21
28
|
|
22
|
-
|
29
|
+
opts.on '--log-level LEVEL', %w(debug info warn error fatal),
|
30
|
+
'set the minimum level of messages to log: [debug, info, warn, error, fatal] (default: warn)' do |level|
|
31
|
+
options[:log_level] = level
|
32
|
+
end
|
23
33
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
val ||= ''
|
28
|
-
options[:attributes][key] = val
|
29
|
-
end
|
34
|
+
opts.on '-o FILE', '--output=FILE', 'set the output filename or stream' do |file|
|
35
|
+
options[:output_file] = file
|
36
|
+
end
|
30
37
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
38
|
+
opts.on '--preserve-conditionals', 'preserve preprocessor conditional directives in the reduced source' do
|
39
|
+
options[:preserve_conditionals] = true
|
40
|
+
end
|
35
41
|
|
36
|
-
|
37
|
-
|
38
|
-
|
42
|
+
opts.on '-q', '--quiet', 'suppress all application log messages' do
|
43
|
+
options[:log_level] = nil
|
44
|
+
end
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
opts.on '-rLIBRARY', '--require LIBRARY', 'require the specified library or libraries before reducing',
|
47
|
+
'may be specified multiple times' do |path|
|
48
|
+
(options[:requires] ||= []).concat path.split ','
|
49
|
+
end
|
43
50
|
|
44
|
-
|
45
|
-
|
46
|
-
|
51
|
+
opts.on '-S', '--safe-mode SAFE_MODE', ['unsafe', 'safe', 'server', 'secure'],
|
52
|
+
'set safe mode level: [unsafe, safe, server, secure] (default: unsafe)' do |name|
|
53
|
+
options[:safe] = name.to_sym
|
54
|
+
end
|
47
55
|
|
48
|
-
|
49
|
-
|
50
|
-
|
56
|
+
opts.on '--trace', 'trace the cause of application errors (default: false)' do
|
57
|
+
options[:trace] = true
|
58
|
+
end
|
51
59
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
60
|
+
opts.on '-v', '--version', 'display the version information and exit' do
|
61
|
+
print_version opts
|
62
|
+
return 0
|
63
|
+
end
|
56
64
|
|
57
|
-
|
58
|
-
|
65
|
+
opts.on '-h', '--help', 'display this help text and exit' do
|
66
|
+
print_help opts
|
67
|
+
return 0
|
68
|
+
end
|
59
69
|
end
|
60
70
|
|
61
|
-
|
62
|
-
|
63
|
-
|
71
|
+
if (args = opt_parser.parse args).empty?
|
72
|
+
opt_parser.warn 'Please specify an AsciiDoc file to reduce.'
|
73
|
+
print_help opt_parser
|
74
|
+
1
|
75
|
+
elsif args.size == 1
|
76
|
+
if (requires = options.delete :requires)
|
77
|
+
requires.uniq.each do |path|
|
78
|
+
require path
|
79
|
+
rescue ::LoadError
|
80
|
+
$stderr.puts %(#{opt_parser.program_name}: '#{path}' could not be required (reason: #{$!.message}))
|
81
|
+
return 1
|
82
|
+
end
|
83
|
+
end
|
84
|
+
options[:input_file] = args[0]
|
85
|
+
options[:output_file] = '-' unless options[:output_file]
|
86
|
+
[0, options]
|
87
|
+
else
|
88
|
+
opt_parser.warn %(extra arguments detected (unparsed arguments: #{(args.drop 1).join ' '}))
|
89
|
+
print_help opt_parser
|
90
|
+
1
|
64
91
|
end
|
92
|
+
rescue ::OptionParser::InvalidOption
|
93
|
+
$stderr.puts %(#{opt_parser.program_name}: #{$!.message})
|
94
|
+
print_help opt_parser
|
95
|
+
1
|
96
|
+
end
|
65
97
|
|
66
|
-
|
67
|
-
|
68
|
-
|
98
|
+
def run args = ARGV
|
99
|
+
code, options = parse (Array args)
|
100
|
+
return code unless code == 0 && options
|
101
|
+
trace = options.delete :trace
|
102
|
+
old_logger = ::Asciidoctor::LoggerManager.logger
|
103
|
+
if (log_level = options.delete :log_level)
|
104
|
+
(options[:logger] = ::Asciidoctor::Logger.new $stderr).level = log_level
|
105
|
+
else
|
106
|
+
options[:logger] = nil
|
69
107
|
end
|
108
|
+
options[:to] = (output_file = options.delete :output_file) == '-' ? $stdout : (::Pathname.new output_file)
|
109
|
+
input = (input_file = options.delete :input_file) == '-' ? $stdin : (::Pathname.new input_file)
|
110
|
+
::Asciidoctor::Reducer.reduce input, options
|
111
|
+
0
|
112
|
+
rescue ::SignalException
|
113
|
+
$stderr.puts if ::Interrupt === $!
|
114
|
+
$!.signo
|
115
|
+
rescue
|
116
|
+
raise $! if trace
|
117
|
+
$stderr.puts %(asciidoctor-reducer: #{$!.message.delete_prefix 'asciidoctor: '})
|
118
|
+
$stderr.puts ' Use --trace to show backtrace'
|
119
|
+
1
|
120
|
+
ensure
|
121
|
+
::Asciidoctor::LoggerManager.logger = old_logger if old_logger
|
70
122
|
end
|
71
123
|
|
72
|
-
|
124
|
+
private
|
73
125
|
|
74
|
-
|
75
|
-
|
76
|
-
print_help opt_parser
|
77
|
-
1
|
78
|
-
elsif args.size == 1
|
79
|
-
if (requires = options.delete :requires)
|
80
|
-
requires.uniq.each do |path|
|
81
|
-
require path
|
82
|
-
rescue ::LoadError
|
83
|
-
$stderr.puts %(#{opt_parser.program_name}: '#{path}' could not be required (reason: #{$!.message}))
|
84
|
-
return 1
|
85
|
-
end
|
86
|
-
end
|
87
|
-
options[:input_file] = args[0]
|
88
|
-
options[:output_file] = '-' unless options[:output_file]
|
89
|
-
[0, options]
|
90
|
-
else
|
91
|
-
opt_parser.warn %(extra arguments detected (unparsed arguments: #{(args.drop 1).join ' '}))
|
92
|
-
print_help opt_parser
|
93
|
-
1
|
126
|
+
def print_help opt_parser
|
127
|
+
$stdout.puts opt_parser.help.chomp
|
94
128
|
end
|
95
|
-
rescue ::OptionParser::InvalidOption
|
96
|
-
$stderr.puts %(#{opt_parser.program_name}: #{$!.message})
|
97
|
-
print_help opt_parser
|
98
|
-
1
|
99
|
-
end
|
100
129
|
|
101
|
-
|
102
|
-
|
103
|
-
return code unless code == 0 && options
|
104
|
-
trace = options.delete :trace
|
105
|
-
old_logger = ::Asciidoctor::LoggerManager.logger
|
106
|
-
if (log_level = options.delete :log_level)
|
107
|
-
(options[:logger] = ::Asciidoctor::Logger.new $stderr).level = log_level
|
108
|
-
else
|
109
|
-
options[:logger] = nil
|
130
|
+
def print_version opt_parser
|
131
|
+
$stdout.puts %(#{opt_parser.program_name} #{VERSION})
|
110
132
|
end
|
111
|
-
options[:to] = (output_file = options.delete :output_file) == '-' ? $stdout : (::Pathname.new output_file)
|
112
|
-
input = (input_file = options.delete :input_file) == '-' ? $stdin : (::Pathname.new input_file)
|
113
|
-
::Asciidoctor::Reducer.reduce input, options
|
114
|
-
0
|
115
|
-
rescue ::SignalException
|
116
|
-
$stderr.puts if ::Interrupt === $!
|
117
|
-
$!.signo
|
118
|
-
rescue
|
119
|
-
raise $! if trace
|
120
|
-
$stderr.puts %(asciidoctor-reducer: #{$!.message.delete_prefix 'asciidoctor: '})
|
121
|
-
$stderr.puts ' Use --trace to show backtrace'
|
122
|
-
1
|
123
|
-
ensure
|
124
|
-
::Asciidoctor::LoggerManager.logger = old_logger if old_logger
|
125
133
|
end
|
126
134
|
|
127
|
-
|
128
|
-
|
129
|
-
def print_help opt_parser
|
130
|
-
$stdout.puts opt_parser.help.chomp
|
135
|
+
LOG_LEVELS = (::Logger::Severity.constants false).each_with_object({}) do |level, accum|
|
136
|
+
accum[level.to_s.downcase] = (::Logger::Severity.const_get level) unless level == :UNKNOWN
|
131
137
|
end
|
132
138
|
|
133
|
-
|
134
|
-
$stdout.puts %(#{opt_parser.program_name} #{VERSION})
|
135
|
-
end
|
139
|
+
private_constant :LOG_LEVELS
|
136
140
|
end
|
137
141
|
end
|
@@ -8,7 +8,7 @@ module Asciidoctor::Reducer
|
|
8
8
|
cond_lineno = @lineno
|
9
9
|
result = super
|
10
10
|
return result if @skipping && skip_active
|
11
|
-
drop = @
|
11
|
+
drop = @include_replacements.current[:drop] ||= []
|
12
12
|
if (depth_change = @conditional_stack.size - depth) < 0
|
13
13
|
if skip_active
|
14
14
|
drop.push(*(drop.pop..cond_lineno))
|
@@ -16,24 +16,27 @@ module Asciidoctor::Reducer
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
def key
|
20
|
+
:reducer
|
21
|
+
end
|
22
|
+
|
19
23
|
def prepare_registry registry = nil
|
20
24
|
registry = ::Asciidoctor::Extensions.create(®istry) if ::Proc === registry
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
return registry if ::Asciidoctor::Extensions.groups[key]
|
26
|
+
if registry
|
27
|
+
registry.groups[key] = group
|
28
|
+
registry
|
29
|
+
else
|
30
|
+
::Asciidoctor::Extensions.create key, &group
|
27
31
|
end
|
28
|
-
registry
|
29
32
|
end
|
30
33
|
|
31
34
|
def register
|
32
|
-
::Asciidoctor::Extensions.register
|
35
|
+
::Asciidoctor::Extensions.register key, &group
|
33
36
|
end
|
34
37
|
|
35
38
|
def unregister
|
36
|
-
::Asciidoctor::Extensions.unregister
|
39
|
+
::Asciidoctor::Extensions.groups.delete key # NOTE `Extensions.unregister key` fails if groups is not initialized
|
37
40
|
end
|
38
41
|
end
|
39
42
|
end
|
@@ -2,34 +2,32 @@
|
|
2
2
|
|
3
3
|
module Asciidoctor::Reducer
|
4
4
|
module IncludeDirectiveTracker
|
5
|
+
attr_reader :include_replacements
|
5
6
|
attr_writer :source_lines
|
6
|
-
attr_reader :x_include_replacements
|
7
7
|
|
8
8
|
def self.extended instance
|
9
|
-
instance.instance_variable_set :@
|
10
|
-
instance.instance_variable_set :@
|
11
|
-
instance.instance_variable_set :@x_include_pushed, nil
|
9
|
+
instance.instance_variable_set :@include_replacements, ([{}].extend CurrentPosition)
|
10
|
+
instance.instance_variable_set :@x_reducer, {}
|
12
11
|
end
|
13
12
|
|
14
13
|
def preprocess_include_directive target, attrlist
|
15
|
-
@
|
16
|
-
@
|
14
|
+
@x_reducer[:include_directive_line] = %(include::#{target}[#{attrlist}])
|
15
|
+
@x_reducer[:include_pushed] = false
|
17
16
|
inc_lineno = @lineno # we're currently on the include line, which is 1-based
|
18
17
|
result = super
|
19
|
-
unless @
|
20
|
-
if (ln = peek_line true)
|
21
|
-
|
22
|
-
|
23
|
-
end
|
18
|
+
unless @x_reducer[:include_pushed]
|
19
|
+
if ((ln = peek_line true)&.end_with? ']') && !(unresolved = ln.start_with? 'Unresolved directive in ') &&
|
20
|
+
inc_lineno == @lineno && (unresolved = ln.start_with? 'link:')
|
21
|
+
ln = %(#{ln.slice 0, (ln.length - 1)}role=include])
|
24
22
|
end
|
25
23
|
push_include_replacement inc_lineno, (unresolved ? [ln] : []), unresolved
|
26
24
|
end
|
27
|
-
@
|
25
|
+
@x_reducer.clear
|
28
26
|
result
|
29
27
|
end
|
30
28
|
|
31
29
|
def push_include data, file, path, lineno, attrs
|
32
|
-
@
|
30
|
+
@x_reducer[:include_pushed] = true
|
33
31
|
inc_lineno = @lineno - 1 # we're below the include line, which is 1-based
|
34
32
|
prev_inc_depth = @include_stack.size
|
35
33
|
result = super
|
@@ -38,33 +36,41 @@ module Asciidoctor::Reducer
|
|
38
36
|
end
|
39
37
|
|
40
38
|
def pop_include
|
41
|
-
@
|
39
|
+
@include_replacements.up unless @x_reducer[:include_pushed]
|
42
40
|
super
|
43
41
|
end
|
44
42
|
|
45
43
|
private
|
46
44
|
|
47
45
|
def push_include_replacement lineno, lines, unresolved = false
|
48
|
-
(inc_replacements = @
|
49
|
-
into: inc_replacements.
|
46
|
+
(inc_replacements = @include_replacements) << {
|
47
|
+
into: inc_replacements.pointer,
|
50
48
|
lineno: lineno,
|
51
|
-
line: @
|
49
|
+
line: @x_reducer[:include_directive_line],
|
52
50
|
lines: lines,
|
53
51
|
}
|
54
|
-
inc_replacements.
|
52
|
+
inc_replacements.to_end unless unresolved || lines.empty?
|
55
53
|
nil
|
56
54
|
end
|
57
55
|
end
|
58
56
|
|
59
57
|
module CurrentPosition
|
60
|
-
|
58
|
+
attr_reader :pointer
|
61
59
|
|
62
60
|
def self.extended instance
|
63
|
-
instance.
|
61
|
+
instance.to_end
|
64
62
|
end
|
65
63
|
|
66
64
|
def current
|
67
|
-
self[@
|
65
|
+
self[@pointer]
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_end
|
69
|
+
@pointer = size - 1
|
70
|
+
end
|
71
|
+
|
72
|
+
def up
|
73
|
+
@pointer = current[:into]
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asciidoctor::Reducer
|
4
|
+
class IncludeMapper < ::Asciidoctor::Extensions::TreeProcessor
|
5
|
+
def process doc
|
6
|
+
if doc.extensions.groups[:reducer]
|
7
|
+
unless (includes = doc.catalog[:includes].select {|_, v| v }.keys).empty?
|
8
|
+
doc.source_lines.concat ['', %(//# includes=#{includes.join ','})]
|
9
|
+
end
|
10
|
+
elsif (last_line = doc.source_lines[-1])&.start_with? '//# includes='
|
11
|
+
doc.catalog[:includes].update ((last_line.slice 13, last_line.length).split ',').map {|it| [it, true] }.to_h
|
12
|
+
end
|
13
|
+
doc
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -6,8 +6,8 @@ require_relative 'conditional_directive_tracker'
|
|
6
6
|
module Asciidoctor::Reducer
|
7
7
|
class Preprocessor < ::Asciidoctor::Extensions::Preprocessor
|
8
8
|
def process doc, reader
|
9
|
-
|
10
|
-
|
9
|
+
doc.options[:preserve_conditionals] ?
|
10
|
+
(reader.extend IncludeDirectiveTracker) : (reader.extend ConditionalDirectiveTracker, IncludeDirectiveTracker)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Asciidoctor::Reducer
|
4
4
|
class TreeProcessor < ::Asciidoctor::Extensions::TreeProcessor
|
5
5
|
def process doc
|
6
|
-
if (inc_replacements = doc.reader.
|
6
|
+
if (inc_replacements = doc.reader.include_replacements).size > 1 || !(inc_replacements[0][:drop] || []).empty?
|
7
7
|
inc_replacements[0][:lines] = doc.source_lines.dup
|
8
8
|
inc_replacements.reverse_each do |it|
|
9
9
|
if (into = it[:into])
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciidoctor-reducer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.alpha.
|
4
|
+
version: 1.0.0.alpha.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Allen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-04-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -73,6 +73,8 @@ files:
|
|
73
73
|
- lib/asciidoctor/reducer/conditional_directive_tracker.rb
|
74
74
|
- lib/asciidoctor/reducer/extensions.rb
|
75
75
|
- lib/asciidoctor/reducer/include_directive_tracker.rb
|
76
|
+
- lib/asciidoctor/reducer/include_mapper.rb
|
77
|
+
- lib/asciidoctor/reducer/include_mapper/extension.rb
|
76
78
|
- lib/asciidoctor/reducer/preprocessor.rb
|
77
79
|
- lib/asciidoctor/reducer/tree_processor.rb
|
78
80
|
- lib/asciidoctor/reducer/version.rb
|
@@ -99,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
101
|
- !ruby/object:Gem::Version
|
100
102
|
version: 1.3.1
|
101
103
|
requirements: []
|
102
|
-
rubygems_version: 3.2.
|
104
|
+
rubygems_version: 3.2.33
|
103
105
|
signing_key:
|
104
106
|
specification_version: 4
|
105
107
|
summary: Reduces a composite AsciiDoc document containing includes and conditionals
|