asciisourcerer 0.1.0 → 0.2.1
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/README.adoc +393 -37
- data/lib/asciidoctor/extensions/source-skim-tree-processor/extension.rb +55 -0
- data/lib/asciisourcerer.rb +1 -0
- data/lib/sourcerer/asciidoc.rb +13 -9
- data/lib/sourcerer/attributes_filter.rb +72 -0
- data/lib/sourcerer/rendering.rb +29 -0
- data/lib/sourcerer/source_skim/config.rb +53 -0
- data/lib/sourcerer/source_skim/skimmer.rb +298 -0
- data/lib/sourcerer/source_skim.rb +76 -0
- data/lib/sourcerer/sync/block_parser.rb +245 -0
- data/lib/sourcerer/sync/cast.rb +274 -0
- data/lib/sourcerer/sync.rb +33 -0
- data/lib/sourcerer/util/list_amend.rb +63 -0
- data/lib/sourcerer/util/pathifier.rb +101 -0
- data/lib/sourcerer/version.rb +1 -1
- data/lib/sourcerer.rb +3 -0
- metadata +13 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: abee321c7941006227f85f6a006a9b6ea795f8bcfd0e5c3a5837b11400e43a23
|
|
4
|
+
data.tar.gz: 92dc5d0bfb4435f1d1a42a558ed1aa975d297aff3201a4cd40266da21e86f816
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 70c932c2a7875d27cec949952bc413dce9c240fe19f8fabbcd756bfa1c94d970d0d9d217538d68c2fb7325b4040dc9cae4ad71fa4c595ab89a8ffa6b650aab1d
|
|
7
|
+
data.tar.gz: 39b7c3e368ed5149012f4e07d6c33809d6b11e5e82e75f8562ab5edae9fde98b32928407801cdd6941951d375ac488c008b2857d3378a2115c4767b398194f1a
|
data/README.adoc
CHANGED
|
@@ -1,38 +1,52 @@
|
|
|
1
|
-
:page-layout: default
|
|
2
|
-
:page-permalink: /docs
|
|
3
|
-
:page-nav_order: 1
|
|
4
1
|
= AsciiSourcerer
|
|
5
2
|
// tag::ai-prompt[]
|
|
6
3
|
// Collects AsciiDoc content for presenting to a generative AI prompt
|
|
7
4
|
// Other AI-only prompt matter could go here
|
|
8
|
-
// tag::
|
|
9
|
-
:
|
|
10
|
-
:
|
|
11
|
-
|
|
12
|
-
:
|
|
13
|
-
|
|
14
|
-
:
|
|
15
|
-
:
|
|
16
|
-
:
|
|
17
|
-
:
|
|
18
|
-
:
|
|
19
|
-
:
|
|
20
|
-
|
|
21
|
-
:
|
|
5
|
+
// tag::global-settings[]
|
|
6
|
+
:this_proj_slug: asciisourcerer
|
|
7
|
+
:this_proj_name: AsciiSourcerer
|
|
8
|
+
// tag::universal-settings[]
|
|
9
|
+
// ALL changes within this block must be made in prime template:
|
|
10
|
+
// DocOps/lab/gems/docopslab-dev/templates/README.asciidoc
|
|
11
|
+
:docopslab_src_www_url: https://github.com/DocOps
|
|
12
|
+
:docopslab_domain: docopslab.org
|
|
13
|
+
:docopslab_www_url: https://{docopslab_domain}
|
|
14
|
+
:docopslab_io_www_url: https://docopslab.github.io
|
|
15
|
+
:docopslab_ruby_version: 3.2.7
|
|
16
|
+
:docopslab_src_www_url: https://raw.githubusercontent.com/DocOps
|
|
17
|
+
:docopslab_git_src_uri: git@github.com:DocOps
|
|
18
|
+
:this_proj_src_www_url: {docopslab_src_www_url}/{this_proj_slug}
|
|
19
|
+
:this_proj_src_raw_url: https://raw.githubusercontent.com/DocOps/{this_proj_slug}/main
|
|
20
|
+
:this_proj_src_main_files_url: {this_proj_src_www_url}/blob/main
|
|
21
|
+
:this_proj_src_git_uri: {docopslab_git_src_uri}/{this_proj_slug}.git
|
|
22
|
+
:this_proj_ruby_version: {docopslab_ruby_version}
|
|
23
|
+
// tag::env-settings[]
|
|
24
|
+
:docs_extn:
|
|
22
25
|
ifdef::env-github[]
|
|
23
26
|
:docs_extn: .adoc
|
|
24
|
-
:
|
|
25
|
-
:
|
|
26
|
-
:
|
|
27
|
-
:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
:docs_extn:
|
|
27
|
+
:icons: font
|
|
28
|
+
:caution-caption: :fire:
|
|
29
|
+
:important-caption: :exclamation:
|
|
30
|
+
:note-caption: :paperclip:
|
|
31
|
+
:tip-caption: :bulb:
|
|
32
|
+
:warning-caption: :warning:
|
|
31
33
|
endif::[]
|
|
32
|
-
// end::
|
|
34
|
+
// end::env-settings[]
|
|
35
|
+
// Settings likely to be overridden locally
|
|
36
|
+
:this_prod_slug: {this_proj_slug}
|
|
37
|
+
:this_prod_name: {this_proj_name}
|
|
38
|
+
// end::universal-settings[]
|
|
39
|
+
:this_prod_vrsn_major: 0
|
|
40
|
+
:this_prod_vrsn_minor: 2
|
|
41
|
+
:this_prod_vrsn_majmin: {this_prod_vrsn_major}.{this_prod_vrsn_minor}
|
|
42
|
+
:this_prod_vrsn_patch: 1
|
|
43
|
+
:this_prod_vrsn: {this_prod_vrsn_majmin}.{this_prod_vrsn_patch}
|
|
44
|
+
:next_prod_vrsn: 0.3.0
|
|
45
|
+
// end::global-settings[]
|
|
33
46
|
:toc: macro
|
|
34
|
-
:toclevels:
|
|
35
|
-
|
|
47
|
+
:toclevels: 4
|
|
48
|
+
:this_prod_repo_files_path: {this_proj_src_www_url}/tree/main
|
|
49
|
+
:imagesdir: ./specs/docs
|
|
36
50
|
|
|
37
51
|
AsciiSourcerer is a Ruby library for radical single-sourcing of documentation and product data, primarily from AsciiDoc, YAML, and Liquid templating operations.
|
|
38
52
|
|
|
@@ -47,31 +61,51 @@ Its end user base is expected to be Ruby developers; for user-friendlier applica
|
|
|
47
61
|
The core module is canonically called `Sourcerer` and is usually referred to as such in documentation.
|
|
48
62
|
The module `AsciiSourcerer` serves as an alias to `Sourcerer` in case of namespace conflicts.
|
|
49
63
|
|
|
64
|
+
toc::[]
|
|
65
|
+
|
|
50
66
|
[[capabilities]]
|
|
51
67
|
=== Capabilities
|
|
52
68
|
|
|
53
69
|
The API focuses on a small set of robust primitives that downstream tools can compose.
|
|
54
70
|
|
|
71
|
+
[qanda]
|
|
55
72
|
AsciiDoc extraction::
|
|
56
73
|
Load attributes, transclude tagged snippets, extract tagged regions, and convert documents from AsciiDoc source files.
|
|
57
74
|
|
|
58
75
|
Tag-aware YAML loading::
|
|
59
76
|
Load YAML files while preserving custom tags and optionally resolving embedded AsciiDoc attributes and Liquid/ERB template syntax.
|
|
60
77
|
|
|
78
|
+
Text syncing in source files::
|
|
79
|
+
Synchronise canonical tagged blocks from a prime template into project-local files.
|
|
80
|
+
Supports one-time bootstrapping, ongoing sync, Liquid rendering within managed blocks, and dry-run diffing.
|
|
81
|
+
See <<sync-cast>>.
|
|
82
|
+
|
|
61
83
|
Templating and rendering::
|
|
62
84
|
Render Liquid or ERB templates against YAML data or AsciiDoc attributes.
|
|
63
85
|
|
|
64
86
|
Liquid runtime integration::
|
|
65
87
|
Initialize a Jekyll-routed Liquid runtime with DocOps Lab filters and tags, so Jekyll-compatible templates behave predictably.
|
|
88
|
+
See <<templating-liquid-runtime>>.
|
|
66
89
|
|
|
67
90
|
Build-time generation::
|
|
68
91
|
Generate prebuild artifacts (attributes, snippets, regions) for downstream builds and runtime access.
|
|
92
|
+
See <<pipelines>>.
|
|
69
93
|
|
|
70
94
|
AsciiDoc-to-manpage conversion::
|
|
71
95
|
Build manpages for apps from the docs.
|
|
72
96
|
|
|
73
97
|
AsciiDoc-to-Markdown conversion::
|
|
74
98
|
Convert AsciiDoc documents to Markdown for agentic consumption, with a focus on preserving semantic structure and document frontmatter.
|
|
99
|
+
See <<markdowngrade>>.
|
|
100
|
+
|
|
101
|
+
AsciiDoc source inspection::
|
|
102
|
+
Skim AsciiDoc documents to produce machine-oriented outlines of sections, code blocks, tables, and other semantic elements for tooling and agent consumption.
|
|
103
|
+
See <<source-skim>>.
|
|
104
|
+
|
|
105
|
+
General-purpose utilities::
|
|
106
|
+
Small, dependency-light primitives for list amendment and path classification/enumeration, available under `Sourcerer::Util`.
|
|
107
|
+
Not required internally; useful for downstream callers and scripts.
|
|
108
|
+
See <<utilities>>.
|
|
75
109
|
|
|
76
110
|
All of these operations are meant to be available even before resources like SchemaGraphy and LiquiDoc are loaded.
|
|
77
111
|
Most are best invoked via a <<integrations,downstream API or utility>>, where robust services for _input_ (file read), _output_ (file write), _configuration_, _scripting_, and contextual _enrichment_ may be available via CLI or API.
|
|
@@ -89,6 +123,7 @@ AsciiDoc attributes are key-value pairs defined in AsciiDoc documents that can b
|
|
|
89
123
|
|
|
90
124
|
tagged regions::
|
|
91
125
|
Sections of source files demarcated by `tag::` and `end::` markers, which can be extracted as content snippets for reuse in documentation or other outputs.
|
|
126
|
+
Tagged regions can also be used by <<sync-cast>> to identify content blocks for synchronization across _source_ files.
|
|
92
127
|
|
|
93
128
|
YAML tags::
|
|
94
129
|
Custom YAML tags (ex: `!liquid`, `!attribute`) that provide special processing instructions during YAML loading.
|
|
@@ -114,6 +149,10 @@ Extract attributes and tagged content from AsciiDoc into artifacts that are load
|
|
|
114
149
|
Converter flow::
|
|
115
150
|
Use a custom converter (callable or constant name) to produce specialized output without embedding converter logic into the core rendering pipeline.
|
|
116
151
|
|
|
152
|
+
Source inspection flow::
|
|
153
|
+
Skim an AsciiDoc source document to produce a structured, JSON-ready outline of its sections and key block elements for tooling and agents.
|
|
154
|
+
See <<source-skim>>.
|
|
155
|
+
|
|
117
156
|
[[quickstart]]
|
|
118
157
|
=== Quickstart
|
|
119
158
|
|
|
@@ -122,7 +161,7 @@ Add `asciisourcerer` to your application using Bundler.
|
|
|
122
161
|
.Gemfile addition
|
|
123
162
|
[source,ruby,subs=+attributes]
|
|
124
163
|
----
|
|
125
|
-
gem 'asciisourcerer', '~> {
|
|
164
|
+
gem 'asciisourcerer', '~> {this_prod_vrsn_majmin}'
|
|
126
165
|
----
|
|
127
166
|
|
|
128
167
|
Then require and use it in your Ruby code.
|
|
@@ -137,6 +176,7 @@ Primary API namespaces:
|
|
|
137
176
|
* `Sourcerer::Yaml` for YAML loading with tag preservation and optional attribute resolution.
|
|
138
177
|
* `Sourcerer::Yaml::TagUtils` for tag helper methods (`detag`, `tag_of`, `tag?`).
|
|
139
178
|
* `Sourcerer::Rendering` for template rendering and output orchestration.
|
|
179
|
+
* `Sourcerer::Sync` for canonical block synchronization (<<sync-cast>>).
|
|
140
180
|
|
|
141
181
|
The top-level `Sourcerer.*` methods remain as compatibility delegators.
|
|
142
182
|
This layer is actually *deprecated* and will be removed in AsciiSourcerer 1.0.
|
|
@@ -169,7 +209,7 @@ Sourcerer::AsciiDoc.generate_html(
|
|
|
169
209
|
|
|
170
210
|
If `asciidoctor-html5s` is unavailable at runtime, Sourcerer falls back to the standard `html5` backend.
|
|
171
211
|
|
|
172
|
-
[[
|
|
212
|
+
[[markdowngrade]]
|
|
173
213
|
=== MarkDownGrade (AsciiDoc -> Markdown)
|
|
174
214
|
|
|
175
215
|
`Sourcerer::MarkDownGrade` handles HTML-to-Markdown adaptation.
|
|
@@ -217,8 +257,8 @@ markdown = Sourcerer::MarkDownGrade.convert_html(
|
|
|
217
257
|
puts(markdown)
|
|
218
258
|
----
|
|
219
259
|
|
|
220
|
-
[[
|
|
221
|
-
|
|
260
|
+
[[markdowngrade-migration]]
|
|
261
|
+
==== Migration Mini-Guide (DocOps Lab)
|
|
222
262
|
|
|
223
263
|
For consumers currently using `DocOps/lab/scripts/mark_down_grade.rb`, migrate to Sourcerer in two steps.
|
|
224
264
|
|
|
@@ -235,7 +275,99 @@ Step 2: Verify parity, then remove duplicate script::
|
|
|
235
275
|
Recommended follow-through::
|
|
236
276
|
* Redirect or retire `lab/scripts/README-mark_down_grade.adoc` so AsciiSourcerer remains source-of-truth.
|
|
237
277
|
|
|
238
|
-
[[
|
|
278
|
+
[[sync-cast]]
|
|
279
|
+
=== Sync/Cast: Canonical Block Synchronization
|
|
280
|
+
|
|
281
|
+
Sync/Cast keeps a set of _canonical blocks_ consistent across multiple files.
|
|
282
|
+
Here are some feature-specific terms.
|
|
283
|
+
|
|
284
|
+
prime template::
|
|
285
|
+
A source file containing canonical blocks intended to be synchronised into one or more project-local target files.
|
|
286
|
+
|
|
287
|
+
target file::
|
|
288
|
+
A project-local file that receives synchronised content from a prime template.
|
|
289
|
+
All content outside canonical blocks is preserved verbatim.
|
|
290
|
+
|
|
291
|
+
canonical block::
|
|
292
|
+
A tagged region whose content is owned by the synchronization system.
|
|
293
|
+
Identified by a configurable prefix; the default is `universal-`.
|
|
294
|
+
Override it per call with the `canonical_prefix:` keyword argument.
|
|
295
|
+
|
|
296
|
+
[[sync-cast-tag-syntax]]
|
|
297
|
+
==== Tag syntax
|
|
298
|
+
|
|
299
|
+
Canonical blocks use AsciiDoc-style `tag::`/`end::` markers embedded inside comments.
|
|
300
|
+
Three comment styles are recognized so the same prime can manage files of any type:
|
|
301
|
+
|
|
302
|
+
[cols="3m,5m",options="header"]
|
|
303
|
+
|===
|
|
304
|
+
| Style | Example
|
|
305
|
+
| HTML / Markdown comment
|
|
306
|
+
| <!-- tag::universal-intro[] -->
|
|
307
|
+
| AsciiDoc line comment
|
|
308
|
+
| // tag::universal-intro[]
|
|
309
|
+
| Shell / Ruby / YAML comment
|
|
310
|
+
| # tag::universal-intro[]
|
|
311
|
+
|===
|
|
312
|
+
|
|
313
|
+
The trailing `[]` is optional in all three styles.
|
|
314
|
+
|
|
315
|
+
A tag whose name begins with the configured prefix (default `universal-`) is treated as canonical and managed by Sync/Cast.
|
|
316
|
+
All other tagged regions in a target file are left entirely alone, and their presence beside a canonical block never triggers a warning.
|
|
317
|
+
|
|
318
|
+
[[sync-cast-operations]]
|
|
319
|
+
==== Operations
|
|
320
|
+
|
|
321
|
+
init::
|
|
322
|
+
One-time operation that renders the prime template (the whole file, not just canonical blocks) through Liquid and writes the result as a new target file.
|
|
323
|
+
Use this to bootstrap a repo-local copy of a project template.
|
|
324
|
+
|
|
325
|
+
sync::
|
|
326
|
+
Ongoing operation that scans for canonical blocks, replaces their content with the prime version (after optional Liquid rendering), and leaves everything else verbatim.
|
|
327
|
+
|
|
328
|
+
dry_run: true::
|
|
329
|
+
Pass `dry_run: true` to either operation to compute the result without writing any file.
|
|
330
|
+
The `result.diff` file contains the rendered content (`init`) or a unified diff (`sync`).
|
|
331
|
+
|
|
332
|
+
[NOTE]
|
|
333
|
+
====
|
|
334
|
+
If a canonical block is absent from a target file, `sync` emits a warning.
|
|
335
|
+
That warning is suppressed when the target contains a non-canonical tag sharing the same suffix — for example, `local-intro` alongside canonical `universal-intro` — indicating a deliberate project-local override.
|
|
336
|
+
====
|
|
337
|
+
|
|
338
|
+
[[sync-cast-liquid]]
|
|
339
|
+
==== Liquid variables in blocks
|
|
340
|
+
|
|
341
|
+
Pass a plain Ruby `Hash` as `data:` and its top-level keys become Liquid variables inside every canonical block.
|
|
342
|
+
Nested values follow Liquid dot notation.
|
|
343
|
+
|
|
344
|
+
During `sync`, only canonical block content is rendered.
|
|
345
|
+
During `init`, the entire prime template is rendered.
|
|
346
|
+
Local content in target files is never rendered.
|
|
347
|
+
|
|
348
|
+
[source,markdown]
|
|
349
|
+
----
|
|
350
|
+
<!-- tag::universal-intro[] -->
|
|
351
|
+
This is {{ data.variables.name }} version {{ data.variables.version }}.
|
|
352
|
+
<!-- end::universal-intro[] -->
|
|
353
|
+
----
|
|
354
|
+
|
|
355
|
+
[[sync-cast-bootstrap]]
|
|
356
|
+
==== Bootstrap example
|
|
357
|
+
|
|
358
|
+
[source,ruby]
|
|
359
|
+
----
|
|
360
|
+
Sourcerer::Sync.init(
|
|
361
|
+
'templates/AGENTS.markdown',
|
|
362
|
+
'AGENTS.md',
|
|
363
|
+
data: { 'project' => 'my-gem', 'org' => 'DocOps' }
|
|
364
|
+
)
|
|
365
|
+
----
|
|
366
|
+
|
|
367
|
+
Parent directories are created automatically.
|
|
368
|
+
Pass `dry_run: true` to return the rendered content in `result.diff` without writing any file.
|
|
369
|
+
|
|
370
|
+
[[templating-liquid-runtime]]
|
|
239
371
|
=== Templating and Liquid Runtime
|
|
240
372
|
|
|
241
373
|
Sourcerer supports Liquid and ERB, but its Liquid support is intentionally aligned with Jekyll’s runtime.
|
|
@@ -284,6 +416,169 @@ Downstream filter responsibility::
|
|
|
284
416
|
Sourcerer ships generic Liquid utility filters only.
|
|
285
417
|
Schema-aware filters (including SGYML-specific classification filters) should be provided by downstream tooling such as SchemaGraphy and/or ReleaseHx.
|
|
286
418
|
|
|
419
|
+
[[source-skim]]
|
|
420
|
+
=== SourceSkim
|
|
421
|
+
|
|
422
|
+
`Sourcerer::SourceSkim` generates machine-oriented _skims_ of AsciiDoc source documents.
|
|
423
|
+
|
|
424
|
+
A skim is a structured, JSON/YAML-ready outline of selected source elements:
|
|
425
|
+
sections, code blocks, definition lists, tables, images, and more.
|
|
426
|
+
Skims are intended to help tooling and agents inspect documentation source without ingesting full file contents.
|
|
427
|
+
|
|
428
|
+
.Example: Skim a file for sections and code blocks
|
|
429
|
+
[source,ruby]
|
|
430
|
+
----
|
|
431
|
+
# Tree sections by default
|
|
432
|
+
skim = Sourcerer::SourceSkim.skim_file('docs/install.adoc')
|
|
433
|
+
|
|
434
|
+
# Both tree and flat section shapes
|
|
435
|
+
skim = Sourcerer::SourceSkim.skim_file('docs/install.adoc', forms: [:tree, :flat])
|
|
436
|
+
|
|
437
|
+
# Restrict to specific categories
|
|
438
|
+
skim = Sourcerer::SourceSkim.skim_file('docs/install.adoc', categories: [:code_blocks, :tables])
|
|
439
|
+
|
|
440
|
+
# Skim inline content
|
|
441
|
+
skim = Sourcerer::SourceSkim.skim_string(raw_adoc_content)
|
|
442
|
+
----
|
|
443
|
+
|
|
444
|
+
Section shapes::
|
|
445
|
+
Pass `forms: [:tree]` (default), `forms: [:flat]`, or both.
|
|
446
|
+
Tree shape preserves nesting; flat shape adds `parent_id` and expresses child section IDs as an array.
|
|
447
|
+
|
|
448
|
+
Categories::
|
|
449
|
+
Default output includes `attributes_custom`, `definition_lists`, `code_blocks`, `literal_blocks`, `examples`, `sidebars`, `tables`, and `images`.
|
|
450
|
+
Opt-in only (excluded by default): `attributes_builtin`, `admonitions`, `quotes`.
|
|
451
|
+
Pass `categories:` with an explicit array of symbols to restrict or expand output.
|
|
452
|
+
|
|
453
|
+
Output reference::
|
|
454
|
+
The skim output schema is at `specs/data/asciidoc-source-skim.schema.json` and a YAML model reference at `specs/data/asciidoc-source-skim-model.yaml`.
|
|
455
|
+
|
|
456
|
+
[[skim-asciidoctor-extension]]
|
|
457
|
+
==== Asciidoctor extension
|
|
458
|
+
`Sourcerer::SourceSkim::TreeProcessorExtension` integrates SourceSkim into Asciidoctor parsing pipelines.
|
|
459
|
+
It stores the result as the `source-skim-result` document attribute and reads `source-skim-forms` and `source-skim-categories` document attributes for per-document configuration.
|
|
460
|
+
|
|
461
|
+
.Register the extension
|
|
462
|
+
[source,ruby]
|
|
463
|
+
----
|
|
464
|
+
require 'asciidoctor/extensions/source-skim-tree-processor/extension'
|
|
465
|
+
Asciidoctor::Extensions.register Sourcerer::SourceSkim::TreeProcessorExtension
|
|
466
|
+
----
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
[[utilities]]
|
|
470
|
+
=== Utilities
|
|
471
|
+
|
|
472
|
+
`Sourcerer::Util` hosts small, dependency-light primitives intended for use by downstream callers and scripts.
|
|
473
|
+
They are not required internally; require the appropriate file explicitly when you need it.
|
|
474
|
+
|
|
475
|
+
Neither utility carries any new runtime dependencies beyond the standard library.
|
|
476
|
+
|
|
477
|
+
[[util-list-amend]]
|
|
478
|
+
==== `Sourcerer::Util::ListAmend`
|
|
479
|
+
|
|
480
|
+
Merges a user-supplied list into a default list using `+`/`-` amendment tokens.
|
|
481
|
+
|
|
482
|
+
.Require
|
|
483
|
+
[source,ruby]
|
|
484
|
+
----
|
|
485
|
+
require 'sourcerer/util/list_amend'
|
|
486
|
+
----
|
|
487
|
+
|
|
488
|
+
.API
|
|
489
|
+
[source,ruby]
|
|
490
|
+
----
|
|
491
|
+
Sourcerer::Util::ListAmend.apply(default_list, custom_list, normalize: nil) -> Array<String>
|
|
492
|
+
----
|
|
493
|
+
|
|
494
|
+
Behavior::
|
|
495
|
+
`nil` / empty custom:::
|
|
496
|
+
Returns `default_list` (stringified) unchanged.
|
|
497
|
+
Fixed-list mode:::
|
|
498
|
+
If `custom_list` contains *no* tokens starting with `+` or `-`, it fully replaces `default_list`.
|
|
499
|
+
Amendment mode:::
|
|
500
|
+
If `custom_list` contains *any* `+`/`-` token:
|
|
501
|
+
`-slug` removes `slug` from the working set (or no-op if absent). +
|
|
502
|
+
`+slug` adds `slug` if not already present. +
|
|
503
|
+
bare `slug` is treated as `+slug`.
|
|
504
|
+
|
|
505
|
+
`normalize` (optional)::
|
|
506
|
+
A callable used to compare items during deduplication and removal, for example `->(s) { s.downcase }`.
|
|
507
|
+
|
|
508
|
+
.Examples
|
|
509
|
+
[source,ruby]
|
|
510
|
+
----
|
|
511
|
+
defaults = %w[a b c]
|
|
512
|
+
|
|
513
|
+
# nil → unchanged
|
|
514
|
+
Sourcerer::Util::ListAmend.apply(defaults, nil) # => ["a", "b", "c"]
|
|
515
|
+
|
|
516
|
+
# fixed list
|
|
517
|
+
Sourcerer::Util::ListAmend.apply(defaults, "b c") # => ["b", "c"]
|
|
518
|
+
|
|
519
|
+
# amendment: remove b, add d
|
|
520
|
+
Sourcerer::Util::ListAmend.apply(defaults, "-b +d") # => ["a", "c", "d"]
|
|
521
|
+
|
|
522
|
+
# amendment: bare token treated as addition
|
|
523
|
+
Sourcerer::Util::ListAmend.apply(defaults, "-b d") # => ["a", "c", "d"]
|
|
524
|
+
----
|
|
525
|
+
|
|
526
|
+
[[util-pathifier]]
|
|
527
|
+
==== `Sourcerer::Util::Pathifier`
|
|
528
|
+
|
|
529
|
+
Classifies an input string as `:file`, `:dir`, `:glob`, or `:missing` and provides a lazy enumerator of matching paths.
|
|
530
|
+
Directory traversal is enumerator-based to avoid materializing large path arrays.
|
|
531
|
+
|
|
532
|
+
.Require
|
|
533
|
+
[source,ruby]
|
|
534
|
+
----
|
|
535
|
+
require 'sourcerer/util/path_matcher'
|
|
536
|
+
----
|
|
537
|
+
|
|
538
|
+
.API
|
|
539
|
+
[source,ruby]
|
|
540
|
+
----
|
|
541
|
+
result = Sourcerer::Util::Pathifier.match(input, recursive: true, include_dirs: false, follow_symlinks: false)
|
|
542
|
+
# result.type -> :file | :dir | :glob | :missing
|
|
543
|
+
# result.input -> original input string
|
|
544
|
+
# result.enum -> Enumerator<String> of matching paths
|
|
545
|
+
----
|
|
546
|
+
|
|
547
|
+
Classification rules::
|
|
548
|
+
`:file`::: `File.file?(input)` is true.
|
|
549
|
+
`:dir`::: `File.directory?(input)` is true.
|
|
550
|
+
`:glob`::: Input contains glob metacharacters (`* ? [ ] { }`).
|
|
551
|
+
`:missing`::: None of the above.
|
|
552
|
+
|
|
553
|
+
Options::
|
|
554
|
+
`recursive`::: Traverse directories recursively via `Find.find` (default: `true`).
|
|
555
|
+
`include_dirs`::: Also yield directory paths during traversal (default: `false`).
|
|
556
|
+
`follow_symlinks`::: Follow symlink directories during recursion (default: `false`).
|
|
557
|
+
|
|
558
|
+
.Examples
|
|
559
|
+
[source,ruby]
|
|
560
|
+
----
|
|
561
|
+
# File
|
|
562
|
+
r = Sourcerer::Util::Pathifier.match('docs/install.adoc')
|
|
563
|
+
r.type # => :file
|
|
564
|
+
r.enum.to_a # => ["/absolute/path/docs/install.adoc"]
|
|
565
|
+
|
|
566
|
+
# Directory (lazy recursive)
|
|
567
|
+
r = Sourcerer::Util::Pathifier.match('docs/')
|
|
568
|
+
r.type # => :dir
|
|
569
|
+
r.enum.select { |p| p.end_with?('.adoc') } # lazy filter
|
|
570
|
+
|
|
571
|
+
# Glob
|
|
572
|
+
r = Sourcerer::Util::Pathifier.match('docs/**/*.adoc')
|
|
573
|
+
r.type # => :glob
|
|
574
|
+
r.enum.to_a # => all matching files
|
|
575
|
+
|
|
576
|
+
# Missing
|
|
577
|
+
r = Sourcerer::Util::Pathifier.match('no/such/path')
|
|
578
|
+
r.type # => :missing
|
|
579
|
+
r.enum.to_a # => []
|
|
580
|
+
----
|
|
581
|
+
|
|
287
582
|
|
|
288
583
|
[[integrations]]
|
|
289
584
|
== Integrations (Implemented and Planned)
|
|
@@ -291,6 +586,9 @@ Schema-aware filters (including SGYML-specific classification filters) should be
|
|
|
291
586
|
These notes describe how AsciiSourcerer relates to existing and future downstream tools.
|
|
292
587
|
For most users, these tools are the recommended way to access AsciiSourcerer’s capabilities, since they provide a richer context for configuration, input/output management, and workflow orchestration.
|
|
293
588
|
|
|
589
|
+
https://github.com/DocOps/lab/tree/main/gems/docopslab-dev[docopslab-dev]::
|
|
590
|
+
A harness for DocOps Lab developer tasks and operations.
|
|
591
|
+
|
|
294
592
|
SchemaGraphy::
|
|
295
593
|
SchemaGraphy's API is the schema-aware layer in the DocOps Lab ecosystem.
|
|
296
594
|
Sourcerer provides it with primitives such as YAML loading, templating, and Liquid runtime setup, while SchemaGraphy handles schema validation and templated-field interpretation.
|
|
@@ -306,6 +604,28 @@ Jekyll Extensions::
|
|
|
306
604
|
DocOps Labs maintains plugins, themes, and even a utility for generating technical documentation with the Jekyll static-site generator.
|
|
307
605
|
All the benefits of extended YAML ingest and Liquid processing are available via these extensions, along with and usually through SchemaGraphy.
|
|
308
606
|
|
|
607
|
+
[[alpha-scripts]]
|
|
608
|
+
=== Alpha Scripts/CLIs
|
|
609
|
+
|
|
610
|
+
The AsciiSourcerer repo does host some CLI utilities and scripts that make direct usage of APIs hosted in the `asciisourcerer` gem.
|
|
611
|
+
These are largely prototype utilities that will eventually make it into official DocOps Lab applications with proper I/O surfaces.
|
|
612
|
+
|
|
613
|
+
[WARNING]
|
|
614
|
+
These scripts are *neither* rigorously tested *nor* officially supported.
|
|
615
|
+
They may be altered, deprecated, or dropped in backward-incompatible ways.
|
|
616
|
+
Use them as examples but do not rely on them in production.
|
|
617
|
+
|
|
618
|
+
To use such a script, copy it from the repo's `scripts/` directory into your project, then run it with `ruby` or `bundle exec ruby` as appropriate.
|
|
619
|
+
|
|
620
|
+
Current scripts include::
|
|
621
|
+
`skim_asciidoc.rb`:::
|
|
622
|
+
For AsciiDoc source inspection.
|
|
623
|
+
Generates YAML or JSON versions of `Sourcerer::SourceSkim` output for a given AsciiDoc document or collection of documents.
|
|
624
|
+
|
|
625
|
+
`mark_down_grade.rb`:::
|
|
626
|
+
For AsciiDoc-to-Markdown conversion.
|
|
627
|
+
This script orchestrates `Sourcerer::AsciiDoc.mark_down_grade` and is a recommended starting point for users needing this functionality without building their own Ruby integration.
|
|
628
|
+
|
|
309
629
|
|
|
310
630
|
[[development]]
|
|
311
631
|
== Development
|
|
@@ -343,7 +663,7 @@ Special developer Rake tasks and libraries are available via the `docopslab-dev`
|
|
|
343
663
|
[.prompt]
|
|
344
664
|
bundle exec rake --tasks | grep labdev:
|
|
345
665
|
|
|
346
|
-
The link:{
|
|
666
|
+
The link:{docopslab_src_www_url}/lab/tree/main/gems/docopslab-dev/README.adoc[DocOps Lab Devtool] or see `.agent/docs/topics/docpslab-devtool.md`.
|
|
347
667
|
|
|
348
668
|
[[api]]
|
|
349
669
|
=== API Design
|
|
@@ -354,13 +674,19 @@ The top-level `Sourcerer.*` methods are deprecated in favor of direct namespace
|
|
|
354
674
|
Do not add new public methods directly to the `Sourcerer` namespace;
|
|
355
675
|
instead, add them to the appropriate submodule.
|
|
356
676
|
|
|
357
|
-
|
|
677
|
+
[[api-shape-policy]]
|
|
678
|
+
==== Ruby API shape policy
|
|
679
|
+
|
|
358
680
|
Use singleton methods (`def self.*`) on namespace modules for stateless primitives.
|
|
681
|
+
|
|
359
682
|
Use classes when behavior is naturally stateful or lifecycle-driven.
|
|
683
|
+
|
|
360
684
|
Use mixin modules for host-integration surfaces (for example, Liquid filters/tags) where the host expects instance methods.
|
|
361
|
-
|
|
685
|
+
Keep public entrypoints as thin wrappers and place transformation logic in an internal helper module/object.
|
|
686
|
+
|
|
687
|
+
[[visibility-policy]]
|
|
688
|
+
==== Visibility policy
|
|
362
689
|
|
|
363
|
-
Visibility policy::
|
|
364
690
|
Use `private_class_method` for singleton helper methods defined with `def self.*`.
|
|
365
691
|
Use `private` for instance helper methods in classes or mixins.
|
|
366
692
|
Avoid exporting helper methods as accidental public API.
|
|
@@ -368,7 +694,7 @@ Avoid exporting helper methods as accidental public API.
|
|
|
368
694
|
[[tests]]
|
|
369
695
|
=== Tests
|
|
370
696
|
|
|
371
|
-
See the full testing documentation at link:{
|
|
697
|
+
See the full testing documentation at link:{this_prod_repo_files_url}/specs/tests/README.adoc[`specs/tests/README.adoc`]
|
|
372
698
|
|
|
373
699
|
Run the RSpec suite:
|
|
374
700
|
|
|
@@ -385,6 +711,36 @@ Run the PR/CI test suite:
|
|
|
385
711
|
[.prompt]
|
|
386
712
|
bundle exec rake pr_test
|
|
387
713
|
|
|
714
|
+
[[release-process]]
|
|
715
|
+
=== Release Process and History
|
|
716
|
+
|
|
717
|
+
AsciiSourcerer is intended to be the most primal gem in the DocOps Lab pool.
|
|
718
|
+
As such, its development is less formal.
|
|
719
|
+
|
|
720
|
+
Each release is tested against all downstream gems and tools, but we are somewhat less formal about issue tracking and development branch management, at least in early stages.
|
|
721
|
+
|
|
722
|
+
Standard release flow:
|
|
723
|
+
|
|
724
|
+
. Update version in `lib/sourcerer/version.rb` and `README.adoc` attributes.
|
|
725
|
+
|
|
726
|
+
. Commit to Git.
|
|
727
|
+
|
|
728
|
+
. Push to GitHub.
|
|
729
|
+
|
|
730
|
+
. Run `./scripts/build.sh` to validate the environment, run tests, and build the gem file to `pkg/`.
|
|
731
|
+
|
|
732
|
+
. Publish to RubyGems.
|
|
733
|
+
+
|
|
734
|
+
RUBYGEMS_API_KEY=<rubygems.org key> ./scripts/publish.sh
|
|
735
|
+
|
|
736
|
+
. Tag the release in Git:
|
|
737
|
+
+
|
|
738
|
+
[.prompt,subs=+attributes]
|
|
739
|
+
git tag v{this_prod_vrsn} && git push origin v{this_prod_vrsn}`.
|
|
740
|
+
|
|
741
|
+
[NOTE]
|
|
742
|
+
AsciiSourcerer does not yet publish a release history document.
|
|
743
|
+
|
|
388
744
|
|
|
389
745
|
[[legal]]
|
|
390
746
|
== Legal
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'asciidoctor/extensions'
|
|
4
|
+
require_relative '../../../sourcerer/source_skim'
|
|
5
|
+
|
|
6
|
+
module Sourcerer
|
|
7
|
+
module SourceSkim
|
|
8
|
+
# Asciidoctor TreeProcessor extension that runs a SourceSkim pass on the
|
|
9
|
+
# document immediately after parsing and stores the result as the document
|
|
10
|
+
# attribute +source-skim-result+.
|
|
11
|
+
#
|
|
12
|
+
# The skim is keyed by symbol (+:title+, +:sections_tree+, etc.) so it is
|
|
13
|
+
# ready for direct use in Ruby without a JSON round-trip.
|
|
14
|
+
#
|
|
15
|
+
# == Configuration via document attributes
|
|
16
|
+
#
|
|
17
|
+
# +source-skim-forms+:: Comma-separated list of section shapes to emit.
|
|
18
|
+
# Recognized values: +tree+, +flat+. Default: +tree+.
|
|
19
|
+
# +source-skim-categories+:: Comma-separated list of element categories to
|
|
20
|
+
# include. Omit to use the default set (everything except
|
|
21
|
+
# +attributes_builtin+).
|
|
22
|
+
#
|
|
23
|
+
# == Usage
|
|
24
|
+
#
|
|
25
|
+
# === API
|
|
26
|
+
#
|
|
27
|
+
# require 'asciidoctor/extensions/source-skim-tree-processor/extension'
|
|
28
|
+
#
|
|
29
|
+
# Asciidoctor::Extensions.register Sourcerer::SourceSkim::TreeProcessorExtension
|
|
30
|
+
#
|
|
31
|
+
# doc = Asciidoctor.load_file('my.adoc', safe: :safe, sourcemap: true)
|
|
32
|
+
# skim = doc.attr('source-skim-result')
|
|
33
|
+
#
|
|
34
|
+
# === With asciidoctor CLI
|
|
35
|
+
#
|
|
36
|
+
# asciidoctor -r ./lib/asciidoctor/extensions/source-skim-tree-processor/extension.rb \
|
|
37
|
+
# -a source-skim-forms=tree,flat \
|
|
38
|
+
# -a source-skim-categories=sections,code_blocks,admonitions \
|
|
39
|
+
# my.adoc
|
|
40
|
+
class TreeProcessorExtension < Asciidoctor::Extensions::TreeProcessor
|
|
41
|
+
def process document
|
|
42
|
+
raw_forms = document.attr('source-skim-forms', 'tree')
|
|
43
|
+
forms = raw_forms.split(',').map { |f| f.strip.to_sym }
|
|
44
|
+
|
|
45
|
+
raw_cats = document.attr('source-skim-categories')
|
|
46
|
+
categories = raw_cats&.split(',')&.map { |c| c.strip.to_sym }
|
|
47
|
+
|
|
48
|
+
config = Config.new(forms: forms, categories: categories)
|
|
49
|
+
skim = Skimmer.new.process(document, config: config)
|
|
50
|
+
document.set_attr('source-skim-result', skim)
|
|
51
|
+
nil
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/asciisourcerer.rb
CHANGED