asciidoctor-reducer 1.0.0-rc.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: de2091cf932e336783f5622831333d3461fc8ee8cf1b47431fe48ba257e759ef
4
+ data.tar.gz: 07e125f547be6892cba77ba5af468ab86a5b37009abe9da4167f3a2f71f45a5e
5
+ SHA512:
6
+ metadata.gz: 9bfa607af1fe8339e4b8925d5e68d793d992c069b674ee40d00234b8e06c254b0d473f7ec4db140b1c95f4446218d347661872eaa72e306785fa9e6d8f593f13
7
+ data.tar.gz: 0ed27e9fbe39fd738cb7a48b22b2f5ea1d967a8cb0077e79dd4ec0e86a3328d9e546f249fb0debda4984485bcf2538905ba8b5da44485b79cd50e2e05001780a
data/CHANGELOG.adoc ADDED
@@ -0,0 +1,198 @@
1
+ = Asciidoctor Reducer Changelog
2
+ :url-repo: https://github.com/asciidoctor/asciidoctor-reducer
3
+
4
+ This document provides a curated view of the changes to Asciidoctor Reducer in each release.
5
+ For a detailed view of what has changed, refer to the {url-repo}/commits/main[commit history] on GitHub.
6
+
7
+ == 1.0.0-rc.1 (2022-04-22) - @mojavelinux
8
+
9
+ _No changes since previous release._
10
+
11
+ === Details
12
+
13
+ {url-repo}/releases/tag/v1.0.0-rc.1[git tag] | {url-repo}/compare/v1.0.0-beta.1\...v1.0.0-rc.1[full diff]
14
+
15
+ == 1.0.0-beta.1 (2022-04-21) - @mojavelinux
16
+
17
+ === Changed
18
+
19
+ * Add names of include files which have been included partially in include mapping comment and prefix names with ~
20
+
21
+ === Details
22
+
23
+ {url-repo}/releases/tag/v1.0.0-beta.1[git tag] | {url-repo}/compare/v1.0.0.alpha.10\...v1.0.0-beta.1[full diff]
24
+
25
+ == 1.0.0.alpha.10 (2022-04-21) - @mojavelinux
26
+
27
+ === Changed
28
+
29
+ * Set Ruby 2.7 as minimum Ruby version
30
+
31
+ === Details
32
+
33
+ {url-repo}/releases/tag/v1.0.0.alpha.10[git tag] | {url-repo}/compare/v1.0.0.alpha.9\...v1.0.0.alpha.10[full diff]
34
+
35
+ == 1.0.0.alpha.9 (2022-04-21) - @mojavelinux
36
+
37
+ === Added
38
+
39
+ * Add `Asciidoctor::Reducer::IncludeMapper` auxiliary extension, required by `asciidoctor/reducer/include_mapper/extension` (#26)
40
+ * Register `Asciidoctor::Reducer::IncludeMapper` extension when `asciidoctor/reducer/include_mapper` is required (#26)
41
+ * Add `Asciidoctor::Reducer::Extensions.key` method that returns key for registering extension group
42
+ * Update help text to note that the `-a` and `-r` CLI options may be specified multiple times
43
+ * Automate the release process
44
+
45
+ === Changed
46
+
47
+ * Rename x_include_replacements attr on reader to include_replacements since it's public
48
+ * Don't pass `:to` option to `Asciidoctor.load_file`
49
+ * Make `Asciidoctor::Reducer::Cli` a module instead of a class
50
+
51
+ === Fixed
52
+
53
+ * Replace remote include with link if `allow-uri-read` attribute is not set
54
+ * Don't raise error if `Asciidoctor::Reducer::Extensions.unregister` is called when extensions are not registered globally
55
+ * Ensure output is written to file with universal newlines (\n) on Windows
56
+
57
+ === Details
58
+
59
+ {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]
60
+
61
+ == 1.0.0.alpha.8 (2022-02-23) - @mojavelinux
62
+
63
+ === Added
64
+
65
+ * Add secure mode as value of `-S` CLI option (#31)
66
+ * Add `--trace` option to CLI to trace cause of application errors (#29)
67
+
68
+ === Changed
69
+
70
+ * Replace include directive with link macro if safe mode is secure (#31)
71
+ * Track line numbers in include replacements using 1-based index
72
+ * Only mix in preprocessor conditional tracker if `:preserve_conditionals` option is not set (#36)
73
+
74
+ === Fixed
75
+
76
+ * Handle signals gracefully (#33)
77
+
78
+ === Details
79
+
80
+ {url-repo}/releases/tag/v1.0.0.alpha.8[git tag] | {url-repo}/compare/v1.0.0.alpha.7\...v1.0.0.alpha.8[full diff]
81
+
82
+ == 1.0.0.alpha.7 (2022-02-14) - @mojavelinux
83
+
84
+ === Added
85
+
86
+ * Add asciidoctor/reducer/api to require main API (#3)
87
+ * Add `Asciidoctor::Reducer.reduce` and `Asciidoctor::Reducer.reduce_file` API methods (#3)
88
+ * Add asciidoctor/reducer/extensions to require extensions API (#3)
89
+ * Add `Asciidoctor::Reducer::Extensions` API (#3)
90
+
91
+ === Changed
92
+
93
+ * Scope extensions to single call instead of registering them globally (#3)
94
+ * Use `:safe` as the default safe mode when using the API
95
+ * Make `CurrentPosition` module private to the `PreprocessorDirectiveTracker` module
96
+
97
+ === Fixed
98
+
99
+ * Require asciidoctor/reducer/version automatically when `Asciidoctor::Reducer::VERSION` is accessed
100
+
101
+ === Details
102
+
103
+ {url-repo}/releases/tag/v1.0.0.alpha.7[git tag] | {url-repo}/compare/v1.0.0.alpha.6\...v1.0.0.alpha.7[full diff]
104
+
105
+ == 1.0.0.alpha.6 (2022-02-10) - @mojavelinux
106
+
107
+ === Added
108
+
109
+ * Add `-S`, `--safe-mode` option to CLI to set safe mode (#13)
110
+ * Add `-r`, `--require` option to CLI to specify additional libraries to require before running (#17)
111
+
112
+ === Changed
113
+
114
+ * Sort CLI options in help text, except for the `-h`, `--help` option
115
+ * Update CLI to always use a new logger instance
116
+ * Defer initializing logger until run method is called
117
+
118
+ === Fixed
119
+
120
+ * Replace include directives that follow an unresolved include (#19)
121
+ * Don't activate reducer extensions on reduced document
122
+ * Prevent custom extension registry from activating extensions twice during reload (#21)
123
+ * Retain includes table in document catalog when reloading document (#23)
124
+
125
+ === Details
126
+
127
+ {url-repo}/releases/tag/v1.0.0.alpha.6[git tag] | {url-repo}/compare/v1.0.0.alpha.5\...v1.0.0.alpha.6[full diff]
128
+
129
+ == 1.0.0.alpha.5 (2022-02-06) - @mojavelinux
130
+
131
+ === Changed
132
+
133
+ * Removing trailing empty lines after reducing when sourcemap is not enabled
134
+ * Remove unnecessary override of lineno in preprocess_include_directive override
135
+ * Simplify how include replacement target is tracked
136
+ * Classify extensions in group named `:reducer`
137
+
138
+ === Fixed
139
+
140
+ * Suppress log messages when reloading document (#14)
141
+
142
+ === Details
143
+
144
+ {url-repo}/releases/tag/v1.0.0.alpha.5[git tag] | {url-repo}/compare/v1.0.0.alpha.4\...v1.0.0.alpha.5[full diff]
145
+
146
+ == 1.0.0.alpha.4 (2022-02-03) - @mojavelinux
147
+
148
+ === Fixed
149
+
150
+ * Fix replacement of nested empty and unresolved includes
151
+
152
+ === Details
153
+
154
+ {url-repo}/releases/tag/v1.0.0.alpha.4[git tag] | {url-repo}/compare/v1.0.0.alpha.3\...v1.0.0.alpha.4[full diff]
155
+
156
+ == 1.0.0.alpha.3 (2022-02-02) - @mojavelinux
157
+
158
+ === Changed
159
+
160
+ * Rename PreprocessorReader ext module to PreprocessorReaderTracker
161
+ * Encapsulate logic to enhance PreprocessorReader inside PreprocessorReaderTracker module
162
+ * Only reload document if source lines have changed; otherwise, update source lines on reader directly
163
+ * Change default safe mode for CLI to :unsafe
164
+
165
+ === Details
166
+
167
+ {url-repo}/releases/tag/v1.0.0.alpha.3[git tag] | {url-repo}/compare/v1.0.0.alpha.2\...v1.0.0.alpha.3[full diff]
168
+
169
+ == 1.0.0.alpha.2 (2022-01-27) - @mojavelinux
170
+
171
+ === Added
172
+
173
+ * Add `-a`, `--attribute` option to CLI for setting an AsciiDoc document attribute at runtime (#6)
174
+
175
+ === Changed
176
+
177
+ * Reduce preprocessor conditionals by default; add option (`--preserve-conditionals`, `:preserve_conditionals`) to preserve them (#8)
178
+ * Don't enable sourcemap automatically (#4)
179
+ * Don't override logger by default; instead, rely on `:logger` API option to change logger
180
+ * Add `--log-level` option to CLI to set severity level on logger (#9)
181
+ * Add `-q`, `--quiet` option to CLI to suppress log messages (#9)
182
+ * Reserve zero index in include replacements for top-level document
183
+
184
+ === Fixed
185
+
186
+ * Preserve return value when overridding `preprocess_include_directive` method
187
+
188
+ === Details
189
+
190
+ {url-repo}/releases/tag/v1.0.0.alpha.2[git tag] | {url-repo}/compare/v1.0.0.alpha.1\...v1.0.0.alpha.2[full diff]
191
+
192
+ == 1.0.0.alpha.1 (2022-01-12) - @mojavelinux
193
+
194
+ Initial release.
195
+
196
+ === Details
197
+
198
+ {url-repo}/releases/tag/v1.0.0.alpha.1[git tag]
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (C) 2021-present Dan Allen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.adoc ADDED
@@ -0,0 +1,363 @@
1
+ = {project-name}
2
+ Dan Allen <https://github.com/mojavelinux[@mojavelinux]>
3
+ v1.0.0-rc.1, 2022-04-22
4
+ :idprefix:
5
+ :idseparator: -
6
+ ifndef::env-github[:icons: font]
7
+ ifdef::env-github[]
8
+ :caution-caption: :fire:
9
+ :important-caption: :exclamation:
10
+ :note-caption: :paperclip:
11
+ :tip-caption: :bulb:
12
+ :warning-caption: :warning:
13
+ endif::[]
14
+ :project-name: Asciidoctor Reducer
15
+ :project-handle: asciidoctor-reducer
16
+ :url-rvm: https://rvm.io
17
+ :url-repo: https://github.com/asciidoctor/{project-handle}
18
+
19
+ {project-name} is a tool that reduces an AsciiDoc document containing include directives to a single AsciiDoc document by expanding the includes reachable from the parent document.
20
+ Additionally, the tool evaluates preprocessor conditionals (unless the option to preserve them is enabled), only keeping those lines from conditions which are true.
21
+ If the document does not contain any preprocessor directives, the tool returns the unmodified source.
22
+
23
+ == Prerequisites
24
+
25
+ {project-name} is a Ruby application that you install using Ruby packaging.
26
+ To install and run {project-name}, you need Ruby 2.7 or better.
27
+
28
+ Run the following command to check which version of Ruby you have installed, if any:
29
+
30
+ $ ruby -v
31
+
32
+ If Ruby is not installed, you can install it using {url-rvm}[RVM] (or, if you prefer, the package manager for your system).
33
+ We generally recommend using RVM as it allows you to install gems without requiring elevated privileges or messing with system libraries.
34
+
35
+ == Installation
36
+
37
+ {project-name} is published to RubyGems.org as the gem named *{project-handle}*.
38
+
39
+ You can install the latest version of the gem using the following command:
40
+
41
+ $ gem install asciidoctor-reducer --pre
42
+
43
+ Installing this gem makes the `asciidoctor-reducer` command available on your $PATH.
44
+ You can also require the gem into the Ruby runtime to use it as a library or Asciidoctor extension.
45
+
46
+ === Project-scoped
47
+
48
+ If you prefer to manage the application as a project-scoped dependency, you can declare the gem in the project's [.path]_Gemfile_:
49
+
50
+ .Gemfile
51
+ [,ruby]
52
+ ----
53
+ source 'https://rubygems.org'
54
+
55
+ gem 'asciidoctor-reducer'
56
+ ----
57
+
58
+ You then install the gem using the `bundle` command:
59
+
60
+ $ bundle --path=.bundle/gems
61
+
62
+ Installing the gem this way makes the `bundle exec asciidoctor-reducer` command available on your $PATH.
63
+
64
+ == Usage
65
+
66
+ === Command
67
+
68
+ You can run this tool using the provided command (i.e., CLI), named `asciidoctor-reducer`.
69
+ To learn how to use the command, and to verify it's available, run the command with the `-h` option:
70
+
71
+ $ asciidoctor-reducer -h
72
+
73
+ On the first line of the help text, you'll see a synopsis of the command:
74
+
75
+ ....
76
+ asciidoctor-reducer [OPTION]... FILE
77
+ ....
78
+
79
+ The argument `FILE` is the AsciiDoc file you want to reduce.
80
+ The options, represented by `+[OPTION]...+`, are optional, as the name suggestions.
81
+
82
+ Thus, to use the command, pass the AsciiDoc file as the sole argument:
83
+
84
+ $ asciidoctor-reducer input.adoc
85
+
86
+ By default, the command will output the reduced AsciiDoc document to the terminal (via stdout).
87
+ To write the output to a file, specify an output file using the `-o` option:
88
+
89
+ $ asciidoctor-reducer -o output.adoc input.adoc
90
+
91
+ The command can also read the input document from stdin instead of a file.
92
+ To use the command in this way, pass `-` as the first argument:
93
+
94
+ $ cat input.adoc | asciidoctor-reducer -
95
+
96
+ To write the output to a file in this case, specify an output file using the `-o` option:
97
+
98
+ $ cat input.adoc | asciidoctor-reducer -o output.adoc -
99
+
100
+ === API
101
+
102
+ You can also use this tool from a Ruby application using the provided API.
103
+ To begin, require the API for this library.
104
+
105
+ [,ruby]
106
+ ----
107
+ require 'asciidoctor/reducer/api'
108
+ ----
109
+
110
+ Next, reduce a parent document that contains includes.
111
+ This works without having to specify the safe mode since the default safe mode when using the API is `:safe`.
112
+
113
+ [,ruby]
114
+ ----
115
+ doc = Asciidoctor::Reducer.reduce_file 'sample.adoc'
116
+ ----
117
+
118
+ Finally, you can retrieve the reduced source from the returned document.
119
+
120
+ [,ruby]
121
+ ----
122
+ puts doc.source
123
+ ----
124
+
125
+ The benefit of this approach is that you can access the reduced source and the parsed document that corresponds to it.
126
+
127
+ If you don't need the parsed document, you can retrieve the reduced source directly by passing the `String` type to the `:to` option:
128
+
129
+ [,ruby]
130
+ ----
131
+ puts Asciidoctor::Reducer.reduce_file 'sample.adoc', to: String
132
+ ----
133
+
134
+ You can write the reduced source directly to a file by passing a file path to the `:to` option:
135
+
136
+ [,ruby]
137
+ ----
138
+ Asciidoctor::Reducer.reduce_file 'sample.adoc', to: 'sample-reduced.adoc'
139
+ ----
140
+
141
+ == Extension
142
+
143
+ Instead of using the API for this library, you can use the load API provided by Asciidoctor.
144
+ If you want to register the extension globally, require the library as follows:
145
+
146
+ [,ruby]
147
+ ----
148
+ require 'asciidoctor/reducer'
149
+ ----
150
+
151
+ When you use the Asciidoctor load API, the document will automatically be reduced.
152
+
153
+ [,ruby]
154
+ ----
155
+ puts (Asciidoctor.load_file 'sample.adoc', safe: :safe).source
156
+ ----
157
+
158
+ If you want to keep the extension scoped to the call, require the library as follows:
159
+
160
+ [,ruby]
161
+ ----
162
+ require 'asciidoctor/reducer/extensions'
163
+ ----
164
+
165
+ Next, use the extensions API to prepare an extension registry and pass it to the Asciidoctor load API:
166
+
167
+ [,ruby]
168
+ ----
169
+ puts (Asciidoctor.load_file 'sample.adoc', safe: :safe, extension_registry: Asciidoctor::Reducer.prepare_registry).source
170
+ ----
171
+
172
+ Working with the extension directly is intended for low-level operations.
173
+ Most of the time, you should use the API provided by this library.
174
+
175
+ == How it Works
176
+
177
+ {project-name} uses a collection of Asciidoctor extensions to rebuild the AsciiDoc source as a single document.
178
+ Top-level include files in the input AsciiDoc document are resolved relative to current working directory.
179
+
180
+ It starts by using a preprocessor extension to enhance the PreprocessorReader class to be notified each time an include is entered (pushed) or exited (popped).
181
+ When an include directive is encountered, the enhanced reader stores the resolved lines and location of the include directive, thus keeping track of where those lines should be inserted in the original source.
182
+ This information is stored as a stack, where each successive entry contains lines to be inserted into a parent entry.
183
+ The enhanced reader also stores the location of preprocessor conditionals and whether the lines they enclose should be kept or dropped.
184
+
185
+ The reducer then uses a tree processor extension to fold the include stack into a single sequence of lines.
186
+ It does so by working from the end of the stack and inserting the lines into the parent until the stack has been flattened.
187
+ As it goes, it also removes lines that have been excluded by the preprocessor conditionals as well as the directive lines themselves (unless the option to preserve conditionals has been specified).
188
+
189
+ Finally, it loads the document again and returns it.
190
+ The reduced source is available on the reconstructed document (via `Document#source` or `Document#source_lines`).
191
+
192
+ === Impact on Extensions
193
+
194
+ If the sourcemap is enabled, and the reducer finds lines to replace or filter, the reducer will load the document again using `Asciidoctor.load`.
195
+ This step is necessary to synchronize the sourcemap with the reduced source.
196
+ This call will cause extensions that run during the load phase to be invoked again.
197
+ An extension can check for this secondary load by checking for the `:reduced` option in the `Document#options` hash.
198
+ If this option is set (the value of which will be `true`), then Asciidoctor is loading the reduced document.
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
+
263
+ == Development
264
+
265
+ Follow the instructions below to learn how to help develop the project or test-drive the development version.
266
+
267
+ === Retrieve the source code
268
+
269
+ Copy the {url-repo}[GitHub repository URL] and pass it to the `git clone` command:
270
+
271
+ [subs=attributes+]
272
+ $ git clone {url-repo}
273
+
274
+ Next, switch to the project directory:
275
+
276
+ [subs=attributes+]
277
+ $ cd {project-handle}
278
+
279
+ === Install the dependencies
280
+
281
+ The dependencies needed to use {project-name} are defined in the [.path]_Gemfile_ at the root of the project.
282
+ You'll use Bundler to install these dependencies.
283
+
284
+ Use the `bundle` command to install the project dependencies under the project directory:
285
+
286
+ $ bundle --path=.bundle/gems
287
+
288
+ You must invoke `bundle` from the project's root directory so it can locate the [.path]_Gemfile_.
289
+
290
+ === Run the tests
291
+
292
+ The test suite is located in the [.path]_spec_ directory.
293
+ The tests are based on RSpec.
294
+
295
+ ==== Run all tests
296
+
297
+ You can run all of the tests using Rake:
298
+
299
+ $ bundle exec spec
300
+
301
+ For more fine-grained control, you can also run the tests directly using RSpec:
302
+
303
+ $ bundle exec rspec
304
+
305
+ To run all tests in a single spec, point RSpec at the spec file:
306
+
307
+ $ bundle exec rspec spec/reducer_spec.rb
308
+
309
+ ==== Run specific tests
310
+
311
+ If you only want to run a single test, or a group of tests, you can do so by tagging the test cases, then filtering the test run using that tag.
312
+
313
+ Start by adding the `only` tag to one or more specifications:
314
+
315
+ [source,ruby]
316
+ ----
317
+ it 'should do something new', only: true do
318
+ expect(true).to be true
319
+ end
320
+ ----
321
+
322
+ Next, run RSpec with the `only` flag enabled:
323
+
324
+ $ bundle exec rspec -t only
325
+
326
+ RSpec will only run the specifications that contain this flag.
327
+
328
+ You can also filter tests by keyword.
329
+ Let's assume we want to run all the tests that have `leveloffset` in the description.
330
+ Run RSpec with the example filter:
331
+
332
+ $ bundle exec rspec -e leveloffset
333
+
334
+ RSpec will only run the specifications that have a description containing the text `leveloffset`.
335
+
336
+ === Generate code coverage
337
+
338
+ To generate a code coverage report when running tests using simplecov, set the `COVERAGE` environment variable as follows when running the tests:
339
+
340
+ $ COVERAGE=deep bundle exec rake
341
+
342
+ You'll see a total coverage score, a detailed coverage report, and a link to HTML report in the output.
343
+ The HTML report helps you understand which lines and branches were missed, if any.
344
+
345
+ === Run the development version
346
+
347
+ When running the `asciidoctor-reducer` command from source, you must prefix the command with `bundle exec`:
348
+
349
+ [subs=attributes+]
350
+ $ bundle exec asciidoctor-reducer sample.adoc
351
+
352
+ To avoid having to do this, or to make the `asciidoctor-reducer` command available from anywhere, you need to build the development gem and install it.
353
+
354
+ == Copyright and License
355
+
356
+ Copyright (C) 2021-present Dan Allen.
357
+ Use of this software is granted under the terms of the MIT License.
358
+
359
+ See the link:LICENSE[LICENSE] for the full license text.
360
+
361
+ == Trademarks
362
+
363
+ AsciiDoc(R) and AsciiDoc Language(TM) are trademarks of the Eclipse Foundation, Inc.
@@ -0,0 +1,39 @@
1
+ begin
2
+ require_relative 'lib/asciidoctor/reducer/version'
3
+ rescue LoadError
4
+ require 'asciidoctor/reducer/version'
5
+ end
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = 'asciidoctor-reducer'
9
+ s.version = Asciidoctor::Reducer::VERSION
10
+ s.summary = 'Reduces an AsciiDoc document containing includes and conditionals to a single AsciiDoc document.'
11
+ s.description = 'A tool that reduces an AsciiDoc document containing preprocessor directives (includes and conditionals) to a single AsciiDoc document by expanding all includes and evaluating all conditionals.'
12
+ s.authors = ['Dan Allen']
13
+ s.email = 'dan.j.allen@gmail.com'
14
+ s.homepage = 'https://asciidoctor.org'
15
+ s.license = 'MIT'
16
+ # NOTE required ruby version is informational only; it's not enforced since it can't be overridden and can cause builds to break
17
+ #s.required_ruby_version = '>= 2.7.0'
18
+ s.metadata = {
19
+ 'bug_tracker_uri' => 'https://github.com/asciidoctor/asciidoctor-reducer/issues',
20
+ 'changelog_uri' => 'https://github.com/asciidoctor/asciidoctor-reducer/blob/main/CHANGELOG.adoc',
21
+ 'mailing_list_uri' => 'https://asciidoctor.zulipchat.com',
22
+ 'source_code_uri' => 'https://github.com/asciidoctor/asciidoctor-reducer'
23
+ }
24
+
25
+ # NOTE the logic to build the list of files is designed to produce a usable package even when the git command is not available
26
+ begin
27
+ files = (result = `git ls-files -z`.split ?\0).empty? ? Dir['**/*'] : result
28
+ rescue
29
+ files = Dir['**/*']
30
+ end
31
+ s.files = files.grep %r/^(?:lib\/.+|LICENSE|(?:CHANGELOG|README)\.adoc|#{s.name}\.gemspec)$/
32
+ s.executables = (files.grep %r/^bin\//).map {|f| File.basename f }
33
+ s.require_paths = ['lib']
34
+
35
+ s.add_runtime_dependency 'asciidoctor', '~> 2.0'
36
+
37
+ s.add_development_dependency 'rake', '~> 13.0.0'
38
+ s.add_development_dependency 'rspec', '~> 3.11.0'
39
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
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'
6
+ exit Asciidoctor::Reducer::Cli.run
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ autoload :Pathname, 'pathname'
4
+ require_relative 'extensions'
5
+
6
+ module Asciidoctor::Reducer
7
+ autoload :VERSION, (::File.join __dir__, 'version.rb')
8
+
9
+ class << self
10
+ # Reduces the AsciiDoc source and either returns the reduced Asciidoctor::Document or writes the source to a file.
11
+ #
12
+ # This method accepts all the options supported by Asciidoctor.load.
13
+ #
14
+ # @param input [String, File, Pathname] the AsciiDoc source to reduce.
15
+ # @param opts [Hash] additional options to configure the behavior of the reducer.
16
+ # @option opts [File, Pathname, Class] :to (nil) the target to which to write the reduced source.
17
+ #
18
+ # @return [Asciidoctor::Document, nil] the reduced document object or nil if the :to option is specified.
19
+ def reduce input, opts = {}
20
+ opts = opts&.merge || {}
21
+ if (extension_registry = Extensions.prepare_registry opts[:extension_registry] || opts[:extensions])
22
+ opts[:extension_registry] = extension_registry
23
+ end
24
+ opts[:safe] ||= :safe
25
+ to = opts.delete :to
26
+ case input
27
+ when ::File
28
+ doc = ::Asciidoctor.load_file input, opts
29
+ when ::Pathname
30
+ doc = ::Asciidoctor.load_file input.to_path, opts
31
+ else
32
+ doc = ::Asciidoctor.load input, opts
33
+ end
34
+ write doc, to
35
+ end
36
+
37
+ # Reduces the AsciiDoc file and either returns the reduced Asciidoctor::Document or writes the source to a file.
38
+ #
39
+ # This method accepts all the options supported by Asciidoctor.load.
40
+ #
41
+ # @param input_file [String] the path of the AsciiDoc file to reduce.
42
+ # @param opts [Hash] additional options to configure the behavior of the reducer.
43
+ # @option opts [File, Pathname, Class] :to (nil) the target to which to write the reduced source.
44
+ #
45
+ # @return [Asciidoctor::Document, nil] the reduced document object or nil if the :to option is specified.
46
+ def reduce_file input_file, opts = {}
47
+ reduce (::Pathname.new input_file), opts
48
+ end
49
+
50
+ private
51
+
52
+ def write doc, to
53
+ return doc unless to && to != '/dev/null'
54
+ output = doc.source
55
+ return output if to == ::String
56
+ output += LF unless output.empty?
57
+ if ::Pathname === to || (!(to.respond_to? :write) && (to = ::Pathname.new to.to_s))
58
+ to.dirname.mkpath
59
+ to.write output, encoding: UTF_8, newline: :universal
60
+ else
61
+ to.write output
62
+ end
63
+ doc
64
+ end
65
+ end
66
+
67
+ LF = ?\n
68
+ UTF_8 = ::Encoding::UTF_8
69
+
70
+ private_constant :LF, :UTF_8
71
+ end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api'
4
+ autoload :OptionParser, 'optparse'
5
+
6
+ module Asciidoctor::Reducer
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
28
+
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
33
+
34
+ opts.on '-o FILE', '--output=FILE', 'set the output filename or stream' do |file|
35
+ options[:output_file] = file
36
+ end
37
+
38
+ opts.on '--preserve-conditionals', 'preserve preprocessor conditional directives in the reduced source' do
39
+ options[:preserve_conditionals] = true
40
+ end
41
+
42
+ opts.on '-q', '--quiet', 'suppress all application log messages' do
43
+ options[:log_level] = nil
44
+ end
45
+
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
50
+
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
55
+
56
+ opts.on '--trace', 'trace the cause of application errors (default: false)' do
57
+ options[:trace] = true
58
+ end
59
+
60
+ opts.on '-v', '--version', 'display the version information and exit' do
61
+ print_version opts
62
+ return 0
63
+ end
64
+
65
+ opts.on '-h', '--help', 'display this help text and exit' do
66
+ print_help opts
67
+ return 0
68
+ end
69
+ end
70
+
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
91
+ end
92
+ rescue ::OptionParser::InvalidOption
93
+ $stderr.puts %(#{opt_parser.program_name}: #{$!.message})
94
+ print_help opt_parser
95
+ 1
96
+ end
97
+
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
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
122
+ end
123
+
124
+ private
125
+
126
+ def print_help opt_parser
127
+ $stdout.puts opt_parser.help.chomp
128
+ end
129
+
130
+ def print_version opt_parser
131
+ $stdout.puts %(#{opt_parser.program_name} #{VERSION})
132
+ end
133
+ end
134
+
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
137
+ end
138
+
139
+ private_constant :LOG_LEVELS
140
+ end
141
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor::Reducer
4
+ module ConditionalDirectiveTracker
5
+ def preprocess_conditional_directive keyword, target, delimiter, text
6
+ skip_active = @skipping
7
+ depth = @conditional_stack.size
8
+ cond_lineno = @lineno
9
+ result = super
10
+ return result if @skipping && skip_active
11
+ drop = @include_replacements.current[:drop] ||= []
12
+ if (depth_change = @conditional_stack.size - depth) < 0
13
+ if skip_active
14
+ drop.push(*(drop.pop..cond_lineno))
15
+ else
16
+ drop << cond_lineno
17
+ end
18
+ elsif depth_change > 0 || cond_lineno == @lineno
19
+ drop << cond_lineno
20
+ else
21
+ drop << [cond_lineno, text]
22
+ end
23
+ result
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'asciidoctor' unless defined? Asciidoctor.load
4
+ require_relative 'preprocessor'
5
+ require_relative 'tree_processor'
6
+
7
+ module Asciidoctor::Reducer
8
+ module Extensions
9
+ module_function
10
+
11
+ def group
12
+ proc do
13
+ next if document.options[:reduced]
14
+ preprocessor Preprocessor
15
+ tree_processor TreeProcessor
16
+ end
17
+ end
18
+
19
+ def key
20
+ :reducer
21
+ end
22
+
23
+ def prepare_registry registry = nil
24
+ registry = ::Asciidoctor::Extensions.create(&registry) if ::Proc === registry
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
31
+ end
32
+ end
33
+
34
+ def register
35
+ ::Asciidoctor::Extensions.register key, &group
36
+ end
37
+
38
+ def unregister
39
+ ::Asciidoctor::Extensions.groups.delete key # NOTE `Extensions.unregister key` fails if groups is not initialized
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor::Reducer
4
+ module IncludeDirectiveTracker
5
+ attr_reader :include_replacements
6
+ attr_writer :source_lines
7
+
8
+ def self.extended instance
9
+ instance.instance_variable_set :@include_replacements, ([{}].extend CurrentPosition)
10
+ instance.instance_variable_set :@x_reducer, {}
11
+ end
12
+
13
+ def preprocess_include_directive target, attrlist
14
+ @x_reducer[:include_directive_line] = %(include::#{target}[#{attrlist}])
15
+ @x_reducer[:include_pushed] = false
16
+ inc_lineno = @lineno # we're currently on the include line, which is 1-based
17
+ result = super
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])
22
+ end
23
+ push_include_replacement inc_lineno, (unresolved ? [ln] : []), unresolved
24
+ end
25
+ @x_reducer.clear
26
+ result
27
+ end
28
+
29
+ def push_include data, file, path, lineno, attrs
30
+ @x_reducer[:include_pushed] = true
31
+ inc_lineno = @lineno - 1 # we're below the include line, which is 1-based
32
+ prev_inc_depth = @include_stack.size
33
+ result = super
34
+ push_include_replacement inc_lineno, (@include_stack.size > prev_inc_depth ? lines : [])
35
+ result
36
+ end
37
+
38
+ def pop_include
39
+ @include_replacements.up unless @x_reducer[:include_pushed]
40
+ super
41
+ end
42
+
43
+ private
44
+
45
+ def push_include_replacement lineno, lines, unresolved = false
46
+ (inc_replacements = @include_replacements) << {
47
+ into: inc_replacements.pointer,
48
+ lineno: lineno,
49
+ line: @x_reducer[:include_directive_line],
50
+ lines: lines,
51
+ }
52
+ inc_replacements.to_end unless unresolved || lines.empty?
53
+ nil
54
+ end
55
+ end
56
+
57
+ module CurrentPosition
58
+ attr_reader :pointer
59
+
60
+ def self.extended instance
61
+ instance.to_end
62
+ end
63
+
64
+ def current
65
+ self[@pointer]
66
+ end
67
+
68
+ def to_end
69
+ @pointer = size - 1
70
+ end
71
+
72
+ def up
73
+ @pointer = current[:into]
74
+ end
75
+ end
76
+
77
+ private_constant :CurrentPosition
78
+ end
@@ -0,0 +1,17 @@
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].map {|name, val| val ? name : %(~#{name}) }).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 ',')
12
+ .map {|it| [(fragment = it.chr == '~') ? (it.slice 1, it.length) : it, !fragment] }.to_h
13
+ end
14
+ doc
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'include_mapper/extension'
4
+
5
+ Asciidoctor::Extensions.register do
6
+ next if document.options[:reduced]
7
+ tree_processor Asciidoctor::Reducer::IncludeMapper
8
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'include_directive_tracker'
4
+ require_relative 'conditional_directive_tracker'
5
+
6
+ module Asciidoctor::Reducer
7
+ class Preprocessor < ::Asciidoctor::Extensions::Preprocessor
8
+ def process doc, reader
9
+ doc.options[:preserve_conditionals] ?
10
+ (reader.extend IncludeDirectiveTracker) : (reader.extend ConditionalDirectiveTracker, IncludeDirectiveTracker)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor::Reducer
4
+ class TreeProcessor < ::Asciidoctor::Extensions::TreeProcessor
5
+ def process doc
6
+ if (inc_replacements = doc.reader.include_replacements).size > 1 || !(inc_replacements[0][:drop] || []).empty?
7
+ inc_replacements[0][:lines] = doc.source_lines.dup
8
+ inc_replacements.reverse_each do |it|
9
+ if (into = it[:into])
10
+ target_lines = inc_replacements[into][:lines]
11
+ # adds extra bit of assurance that we're replacing the correct line
12
+ next unless target_lines[(idx = it[:lineno] - 1)] == it[:line]
13
+ end
14
+ lines = it[:lines]
15
+ unless (drop = it[:drop] || []).empty?
16
+ drop.reverse_each do |drop_it|
17
+ ::Array === drop_it ? (lines[drop_it[0] - 1] = drop_it[1]) : (lines.delete_at drop_it - 1)
18
+ end
19
+ end
20
+ target_lines[idx] = lines if target_lines
21
+ end
22
+ source_lines = inc_replacements[0][:lines].flatten
23
+ if doc.sourcemap
24
+ logger = ::Asciidoctor::LoggerManager.logger
25
+ opts = doc.options.merge logger: nil, parse: false, reduced: true
26
+ if (ext_reg = opts[:extension_registry])
27
+ opts[:extension_registry] = ::Asciidoctor::Extensions::Registry.new ext_reg.groups
28
+ end
29
+ includes = doc.catalog[:includes]
30
+ doc = ::Asciidoctor.load source_lines, opts
31
+ doc.catalog[:includes] = includes
32
+ doc.parse
33
+ ::Asciidoctor::LoggerManager.logger = logger
34
+ else
35
+ source_lines.pop while (source_lines[-1] || :eof).empty?
36
+ doc.reader.source_lines = source_lines
37
+ end
38
+ end
39
+ doc
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor
4
+ module Reducer
5
+ VERSION = '1.0.0-rc.1'
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'reducer/extensions'
4
+
5
+ Asciidoctor::Reducer::Extensions.register
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'asciidoctor/reducer'
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: asciidoctor-reducer
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0-rc.1
5
+ platform: ruby
6
+ authors:
7
+ - Dan Allen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-04-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: asciidoctor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 13.0.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 13.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.11.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.11.0
55
+ description: A tool that reduces an AsciiDoc document containing preprocessor directives
56
+ (includes and conditionals) to a single AsciiDoc document by expanding all includes
57
+ and evaluating all conditionals.
58
+ email: dan.j.allen@gmail.com
59
+ executables:
60
+ - asciidoctor-reducer
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - CHANGELOG.adoc
65
+ - LICENSE
66
+ - README.adoc
67
+ - asciidoctor-reducer.gemspec
68
+ - bin/asciidoctor-reducer
69
+ - lib/asciidoctor-reducer.rb
70
+ - lib/asciidoctor/reducer.rb
71
+ - lib/asciidoctor/reducer/api.rb
72
+ - lib/asciidoctor/reducer/cli.rb
73
+ - lib/asciidoctor/reducer/conditional_directive_tracker.rb
74
+ - lib/asciidoctor/reducer/extensions.rb
75
+ - lib/asciidoctor/reducer/include_directive_tracker.rb
76
+ - lib/asciidoctor/reducer/include_mapper.rb
77
+ - lib/asciidoctor/reducer/include_mapper/extension.rb
78
+ - lib/asciidoctor/reducer/preprocessor.rb
79
+ - lib/asciidoctor/reducer/tree_processor.rb
80
+ - lib/asciidoctor/reducer/version.rb
81
+ homepage: https://asciidoctor.org
82
+ licenses:
83
+ - MIT
84
+ metadata:
85
+ bug_tracker_uri: https://github.com/asciidoctor/asciidoctor-reducer/issues
86
+ changelog_uri: https://github.com/asciidoctor/asciidoctor-reducer/blob/main/CHANGELOG.adoc
87
+ mailing_list_uri: https://asciidoctor.zulipchat.com
88
+ source_code_uri: https://github.com/asciidoctor/asciidoctor-reducer
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">"
101
+ - !ruby/object:Gem::Version
102
+ version: 1.3.1
103
+ requirements: []
104
+ rubygems_version: 3.3.7
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: Reduces an AsciiDoc document containing includes and conditionals to a single
108
+ AsciiDoc document.
109
+ test_files: []