asciidoc-pubkit 0.8.4 → 0.8.6
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.md +29 -0
- data/README.md +84 -13
- data/data/heading-rules.ja.yml +2 -1
- data/data/review-rules.ja.yml +23 -1
- data/data/writing/ja/criteria.md +60 -1
- data/data/writing/ja/headings.md +8 -0
- data/lib/asciidoc_pubkit/cli.rb +6 -3
- data/lib/asciidoc_pubkit/document.rb +76 -1
- data/lib/asciidoc_pubkit/rules.rb +1 -1
- data/lib/asciidoc_pubkit/session.rb +50 -10
- data/lib/asciidoc_pubkit/settings.rb +7 -3
- data/lib/asciidoc_pubkit.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e1fb57dff066c28a30d6205ad30ff8c5cd1a89fc27c35ec8379e9c80354843ae
|
|
4
|
+
data.tar.gz: 9431768603df5a8191ba93b0bc5773ad188050e06304e6f0f35272bbe132ef51
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 901984c71c8178ba62738e21ec67cb5585ebe72719ef06c03b38585c5ad7d0961a9fe4da78c47d1612e9c339d6170bee9a060ea4cf2cf68e9301ae4b80bb96ac
|
|
7
|
+
data.tar.gz: 70570e253745de217ba1d4eb2c5447a7a1dba2f72e3d1f5f1abb40787d54c996fa9dca3072bb190071a459346146200e5744e9eb5fa72f4410c9dd314af71333
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.6 — 2026-10-02
|
|
4
|
+
|
|
5
|
+
- Add separate `review scan --scope lists` sessions for source-mapped single-line
|
|
6
|
+
outline list text. Preserve markers, structure, inline tokens, and other scopes;
|
|
7
|
+
report unsupported or reused-source items as coverage notices.
|
|
8
|
+
- Add opt-in `--preserve-heading-ids` for heading scans. Save exact old-ID anchor
|
|
9
|
+
permissions and verify only those additions immediately before their selected
|
|
10
|
+
headings while retaining section IDs, structure, and protected body content.
|
|
11
|
+
- Advance sessions to schema 3; retain prior baselines and finish
|
|
12
|
+
ongoing reviews with their original tool and schema.
|
|
13
|
+
|
|
14
|
+
## 0.8.5 — 2026-10-02
|
|
15
|
+
|
|
16
|
+
- Refine role-metaphor guidance for 入口: consider the actual creation, invocation,
|
|
17
|
+
configuration, reference, learning, or entry-point role even with a clear
|
|
18
|
+
referent. Require decision-specific evidence and evaluated alternatives rather
|
|
19
|
+
than stock reasons with appended quotations; keep quality checks advisory.
|
|
20
|
+
- Add 入口 as a heading topic candidate while preserving generated IDs and edit
|
|
21
|
+
scopes. Clarify review integrity failure handling and limits of reports about
|
|
22
|
+
excluded lists and other unsupplied content.
|
|
23
|
+
|
|
24
|
+
- Add contextual Japanese revision examples for extension terminology, exposed
|
|
25
|
+
interfaces, layered structures, process tracking, missed events, processing,
|
|
26
|
+
and concise capabilities or obligations. Preserve actors, modality, ordering,
|
|
27
|
+
visibility, counts, and structural distinctions when choosing alternatives.
|
|
28
|
+
- Add extension and indirect-expression candidates, reuse existing tracking
|
|
29
|
+
predicates, and extend configured use/handling potential forms and selected
|
|
30
|
+
operation lemmas with literal-mode surfaces.
|
|
31
|
+
|
|
3
32
|
## 0.8.4 — 2026-10-02
|
|
4
33
|
|
|
5
34
|
- Require passage-specific review decisions in prose and heading prompts instead
|
data/README.md
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
A toolkit for authoring and reviewing AsciiDoc books.
|
|
9
9
|
|
|
10
|
-
Version 0.8.
|
|
11
|
-
prompt, separate prose and
|
|
10
|
+
Version 0.8.6 provides shared Japanese technical writing criteria, an authoring
|
|
11
|
+
prompt, separate prose, heading, and list review prompts, manuscript scoring, and
|
|
12
12
|
baseline verification for edited manuscripts, plus explicit prose-only mechanical
|
|
13
13
|
replacements using a limited prh-format rule set.
|
|
14
14
|
The CLI, diagnostics, documentation, and generated instructions are in English.
|
|
@@ -16,7 +16,7 @@ Japanese text is retained in manuscript excerpts, rule dictionaries, and fixture
|
|
|
16
16
|
|
|
17
17
|
## Available features
|
|
18
18
|
|
|
19
|
-
The following commands are available in version 0.8.
|
|
19
|
+
The following commands are available in version 0.8.6.
|
|
20
20
|
|
|
21
21
|
| Feature | Commands | Behavior |
|
|
22
22
|
| --- | --- | --- |
|
|
@@ -24,6 +24,7 @@ The following commands are available in version 0.8.4.
|
|
|
24
24
|
| [Replacement preview](#prose-replacements) | `replace check`, `replace diff` | Report mechanical replacement candidates or preview a diff for mapped running prose; preserve source files |
|
|
25
25
|
| [Replacement application](#prose-replacements) | `replace apply` | Apply author-supplied rules after checking protected content and document structure; no MeCab or AI required |
|
|
26
26
|
| [Prose review](#review-workflow) | `review scan` | Collect mapped Japanese running prose and contextual review candidates with MeCab/IPADIC by default |
|
|
27
|
+
| [List review](#list-review) | `review scan --scope lists` | Review mapped single-line list text in a separate session |
|
|
27
28
|
| [Heading review](#heading-review) | `review scan --scope headings` | Collect editable section titles separately, retaining the outline and read-only body evidence |
|
|
28
29
|
| [Review prompts](#prompt) | `review prompt` | Generate one Markdown prompt from a saved session for review and editing by an external reviewer |
|
|
29
30
|
| [Baseline verification](#verify) | `review verify` | Check edited sources against a saved baseline for mechanical preservation; meaning is not verified |
|
|
@@ -107,7 +108,7 @@ Add the gem to your project's `Gemfile` to manage its version with Bundler:
|
|
|
107
108
|
|
|
108
109
|
```ruby
|
|
109
110
|
source 'https://rubygems.org'
|
|
110
|
-
gem 'asciidoc-pubkit', '~> 0.8.
|
|
111
|
+
gem 'asciidoc-pubkit', '~> 0.8.6'
|
|
111
112
|
```
|
|
112
113
|
|
|
113
114
|
Then install dependencies and run the CLI through Bundler:
|
|
@@ -129,7 +130,7 @@ git clone https://github.com/cybergarage/asciidoc-pubkit.git
|
|
|
129
130
|
cd asciidoc-pubkit
|
|
130
131
|
bundle install
|
|
131
132
|
gem build asciidoc-pubkit.gemspec
|
|
132
|
-
gem install ./asciidoc-pubkit-0.8.
|
|
133
|
+
gem install ./asciidoc-pubkit-0.8.6.gem
|
|
133
134
|
asciidoc-pubkit --version
|
|
134
135
|
```
|
|
135
136
|
|
|
@@ -153,7 +154,7 @@ asciidoc-pubkit writing prompt --lang ja --output writing-prompt.md
|
|
|
153
154
|
```
|
|
154
155
|
|
|
155
156
|
For example, `--lang en` exits with an unsupported-language error. No English
|
|
156
|
-
review or writing criteria are shipped in 0.8.
|
|
157
|
+
review or writing criteria are shipped in 0.8.6.
|
|
157
158
|
|
|
158
159
|
For a small trial, use `examples/book.adoc` as the scan input. Its Japanese
|
|
159
160
|
paragraphs deliberately contain review candidates; its code block must remain
|
|
@@ -520,8 +521,9 @@ are frozen into the session; scan again after changing them.
|
|
|
520
521
|
|
|
521
522
|
### Heading review
|
|
522
523
|
|
|
523
|
-
Review headings and
|
|
524
|
-
`prose`; `--scope headings` selects section titles
|
|
524
|
+
Review headings, prose, and list text in separate sessions. The default scan scope
|
|
525
|
+
remains `prose`; `--scope headings` selects section titles and `--scope lists` selects
|
|
526
|
+
supported list text. There is no combined scope.
|
|
525
527
|
Default output directories are `.pubkit/review` for prose and `.pubkit/headings`
|
|
526
528
|
for headings, so separate scans do not replace each other by default.
|
|
527
529
|
The scope is saved at scan time; `prompt` and `verify` use that saved scope.
|
|
@@ -564,12 +566,25 @@ and converted inline titles and physical title lines reused by multiple includes
|
|
|
564
566
|
Unresolved section titles receive coverage notices. Verification permits only selected title text changes while
|
|
565
567
|
protecting the body, title markers, hierarchy, order, section IDs, references,
|
|
566
568
|
attributes, includes and other protected content. A title-derived section ID
|
|
567
|
-
change fails verification.
|
|
568
|
-
|
|
569
|
+
change fails verification. To permit limited ID preservation, scan with
|
|
570
|
+
`--scope headings --preserve-heading-ids`. Eligible generated headings then save
|
|
571
|
+
an exact `permitted_id_anchor` in their metadata. A reviewer may insert only that
|
|
572
|
+
anchor immediately before its selected heading, for example:
|
|
573
|
+
|
|
574
|
+
```adoc
|
|
575
|
+
[#_手動圧縮の入口]
|
|
576
|
+
== 手動圧縮と拡張からの起動
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
Verification allows this exact addition while requiring the same section ID,
|
|
580
|
+
hierarchy, order, and protected body. Existing explicit anchors remain protected;
|
|
581
|
+
other anchors and reference migrations are outside this permission. Without the
|
|
582
|
+
flag, only title text is editable. Scan and prompt never insert anchors or rewrite
|
|
583
|
+
manuscripts. Numeric title changes
|
|
569
584
|
are manual-review notices, and remaining candidates do not fail verification.
|
|
570
585
|
`meaning_verified` remains `false`.
|
|
571
586
|
|
|
572
|
-
|
|
587
|
+
Version 0.8.6 uses session schema 3. Earlier sessions must be recreated; preserve or
|
|
573
588
|
finish an ongoing review with its original tool before establishing a new baseline.
|
|
574
589
|
`review score` continues to support prose only and rejects `--scope`.
|
|
575
590
|
|
|
@@ -624,6 +639,13 @@ verification. They request separate reports for mechanical preservation,
|
|
|
624
639
|
candidate decisions, and paragraph or heading quality review, with counts and
|
|
625
640
|
unresolved items. Protected-scope concerns are separate proposals, not evidence
|
|
626
641
|
of editorial approval. Pending items make the review incomplete.
|
|
642
|
+
Version 0.8.5 further requires an individual role or claim, located
|
|
643
|
+
evidence, a considered direct alternative, and the rationale for each candidate
|
|
644
|
+
decision. A stock reason with an appended quotation is insufficient. For `入口`,
|
|
645
|
+
the shared criteria ask whether creation, invocation, configuration, reference,
|
|
646
|
+
or a learning role can be stated directly even when the referent is clear.
|
|
647
|
+
Remaining role metaphors must be checked against those individual decisions.
|
|
648
|
+
|
|
627
649
|
These are reviewer instructions: the gem does not validate a decision ledger
|
|
628
650
|
or prove that an AI or human followed the instructions. Keep session metadata
|
|
629
651
|
and baseline snapshots immutable; format only authorized manuscript spans.
|
|
@@ -1022,6 +1044,17 @@ These are candidates for contextual review, not banned expressions. A necessary
|
|
|
1022
1044
|
condition, uncertainty, or distinction must survive a revision; a redundant
|
|
1023
1045
|
disclaimer can instead be removed or folded into a more precise main claim.
|
|
1024
1046
|
|
|
1047
|
+
Version 0.8.5 extends the existing `入口` question and shared criteria
|
|
1048
|
+
without adding another prose matcher. A known referent alone does not justify
|
|
1049
|
+
vague role wording; direct alternatives are evaluated against the actual
|
|
1050
|
+
operation, conditions, and technical usage. The heading `heading-vague-topic`
|
|
1051
|
+
rule also includes `入口`; proposed title changes must preserve generated IDs
|
|
1052
|
+
or be reported for a separate authorized migration. Lists remain excluded and
|
|
1053
|
+
are not included in prose or heading body evidence. Reports about outside-scope
|
|
1054
|
+
concerns cover only content actually inspected, not unreviewed excluded blocks.
|
|
1055
|
+
If baseline or artifact integrity fails, preserve the evidence and stop editing;
|
|
1056
|
+
never update snapshot hashes or replace the baseline to claim a successful review.
|
|
1057
|
+
|
|
1025
1058
|
Version 0.8.3 also includes scoped candidates such as `構築入口`,
|
|
1026
1059
|
`エラーを回収する`, `ツールを呼ぶ`, `したりできます`, and `設計の肝`.
|
|
1027
1060
|
These additions use the exact surfaces listed in the YAML in both modes;
|
|
@@ -1044,6 +1077,16 @@ precedence. `木全体` is an explicit contextual phrase in both modes because
|
|
|
1044
1077
|
IPADIC can parse `木全` as a surname; this narrowly addresses that segmentation
|
|
1045
1078
|
case without treating all names or compounds containing `木` as trees.
|
|
1046
1079
|
|
|
1080
|
+
Version 0.8.5 additionally reviews `拡張点`, `使えます`, `積み重なります`,
|
|
1081
|
+
`開放しています`, `見落とします`, `扱えます`, `使っています`, and selected indirect
|
|
1082
|
+
phrases. Existing tracking rules cover `追えます`. MeCab uses configured lemmas
|
|
1083
|
+
for use, potential handling, accumulation, oversight, and sahen opening;
|
|
1084
|
+
literal mode uses the listed surfaces. The shared examples distinguish an
|
|
1085
|
+
extension point from its mechanism, layers from a stack, system detection from
|
|
1086
|
+
human oversight, and processing from control. Revisions preserve actors,
|
|
1087
|
+
capabilities and obligations, sequence, visibility, counts, and distribution.
|
|
1088
|
+
These additions need a fresh scan and are contextual review guidance.
|
|
1089
|
+
|
|
1047
1090
|
Metaphorical-operation candidates include limited exact surfaces of
|
|
1048
1091
|
`地味に効く`, `静かに壊れる`, `時間を溶かす`, and `側に倒す`, including selected polite,
|
|
1049
1092
|
past, and connective forms listed in the packaged YAML. They use contextual
|
|
@@ -1096,12 +1139,13 @@ reports analyzer changes instead of treating results from different dictionaries
|
|
|
1096
1139
|
as directly comparable. Prompt generation uses saved evidence and does not need
|
|
1097
1140
|
MeCab. Changed rules or dictionary settings require a new scan.
|
|
1098
1141
|
|
|
1099
|
-
|
|
1142
|
+
Version 0.8.6 uses session schema 3; version 0.8.5 uses schema 2.
|
|
1143
|
+
Sessions with a different schema or tool version cannot be loaded. Keep the original baseline for
|
|
1100
1144
|
an ongoing review and finish it with the original version, or start a new review
|
|
1101
1145
|
pass in a different directory:
|
|
1102
1146
|
|
|
1103
1147
|
```sh
|
|
1104
|
-
asciidoc-pubkit review scan book.adoc --output .pubkit/review-0.8.
|
|
1148
|
+
asciidoc-pubkit review scan book.adoc --output .pubkit/review-0.8.6
|
|
1105
1149
|
```
|
|
1106
1150
|
|
|
1107
1151
|
Severity describes review priority, not proof of an error. There is no AI-authorship
|
|
@@ -1119,6 +1163,33 @@ unambiguously, the paragraph is skipped with a coverage notice. Columns are
|
|
|
1119
1163
|
one-based Unicode character positions, not byte offsets or display widths.
|
|
1120
1164
|
An empty findings array does not establish full coverage or good prose.
|
|
1121
1165
|
|
|
1166
|
+
## List review
|
|
1167
|
+
|
|
1168
|
+
Use a separate session to review list descriptions, including reference-list text:
|
|
1169
|
+
|
|
1170
|
+
```sh
|
|
1171
|
+
asciidoc-pubkit review scan book.adoc --scope lists --output .pubkit/lists
|
|
1172
|
+
asciidoc-pubkit review prompt .pubkit/lists --output lists-review.md
|
|
1173
|
+
asciidoc-pubkit review verify .pubkit/lists
|
|
1174
|
+
```
|
|
1175
|
+
|
|
1176
|
+
The default output directory is `.pubkit/lists`. This scope reuses prose rules,
|
|
1177
|
+
glossary, style, analyzer, and shared writing criteria. It does not include running
|
|
1178
|
+
prose or edit headings. Each selected item appears once with heading context;
|
|
1179
|
+
read additional evidence separately when its technical role cannot be established.
|
|
1180
|
+
|
|
1181
|
+
Only exact source-mapped, single-line simple unordered or ordered item text is
|
|
1182
|
+
editable, including supported nested outline lists. Multiline, description,
|
|
1183
|
+
checklist, compound, ambiguous, and reused-source items remain protected with
|
|
1184
|
+
coverage notices. List markers, nesting, structure, links, and other inline tokens
|
|
1185
|
+
remain protected. Candidate columns include the source marker and indentation.
|
|
1186
|
+
Session JSON retains the `paragraphs` and `paragraph_id` keys, with
|
|
1187
|
+
`kind: list-item` and source `column`, `prefix`, and `suffix` metadata.
|
|
1188
|
+
|
|
1189
|
+
Default prose scanning, scoring, and mechanical replacement keep their existing
|
|
1190
|
+
prose scope. Heading body evidence continues to omit lists. A successful verify
|
|
1191
|
+
checks preservation and does not establish editorial completion.
|
|
1192
|
+
|
|
1122
1193
|
## Development
|
|
1123
1194
|
|
|
1124
1195
|
```sh
|
data/data/heading-rules.ja.yml
CHANGED
|
@@ -12,7 +12,8 @@ terms:
|
|
|
12
12
|
terms:
|
|
13
13
|
- いろいろ
|
|
14
14
|
- さまざまなこと
|
|
15
|
-
|
|
15
|
+
- 入口
|
|
16
|
+
question: 'Check whether the heading identifies the actual subject, operation or comparison. Use the section as evidence; apply the shared role-metaphor criteria to 入口 and preserve section IDs. Do not invent missing specificity.'
|
|
16
17
|
fixed_titles:
|
|
17
18
|
- はじめに
|
|
18
19
|
- 本書の構成
|
data/data/review-rules.ja.yml
CHANGED
|
@@ -34,14 +34,19 @@ terms:
|
|
|
34
34
|
# Review context before choosing a katakana technical term.
|
|
35
35
|
- 木
|
|
36
36
|
- 余白
|
|
37
|
-
question: Identify the concrete referent, components, or measurable work.
|
|
37
|
+
question: Identify the concrete referent, components, role, or measurable work.
|
|
38
|
+
For 入口, apply the shared role-metaphor criteria; a clear referent alone is
|
|
39
|
+
not a sufficient reason to keep vague operation wording. Keep
|
|
38
40
|
established technical meanings. For 木 and 余白, consider a context-appropriate
|
|
39
41
|
katakana term (such as ツリー or マージン) only when it names the intended concept.
|
|
40
42
|
weak-predicate:
|
|
41
43
|
terms:
|
|
42
44
|
# Use, interpretation, and understanding (literal-mode surfaces).
|
|
43
45
|
- 利用します
|
|
46
|
+
- 使えます
|
|
47
|
+
- 使っています
|
|
44
48
|
- 扱います
|
|
49
|
+
- 扱えます
|
|
45
50
|
- 扱いません
|
|
46
51
|
- 意味しません
|
|
47
52
|
- 把握します
|
|
@@ -58,6 +63,7 @@ terms:
|
|
|
58
63
|
- 調べられます
|
|
59
64
|
- 確かめます
|
|
60
65
|
- 探します
|
|
66
|
+
- 見落とします
|
|
61
67
|
- 追えます
|
|
62
68
|
# Inspect retrieval, interpretation, and invocation for any object.
|
|
63
69
|
- 呼ぶ
|
|
@@ -75,6 +81,8 @@ terms:
|
|
|
75
81
|
- 作ります
|
|
76
82
|
- 組み立てられます
|
|
77
83
|
- 組み合わせます
|
|
84
|
+
- 積み重なります
|
|
85
|
+
- 開放しています
|
|
78
86
|
- 成り立たせています
|
|
79
87
|
# Organization, comparison, and selection.
|
|
80
88
|
- 整理します
|
|
@@ -153,6 +161,7 @@ terms:
|
|
|
153
161
|
- エラーを回収する
|
|
154
162
|
- エラーを回収します
|
|
155
163
|
- 介入パターン
|
|
164
|
+
- 拡張点
|
|
156
165
|
# Object-specific everyday verbs, not general bans on these verbs.
|
|
157
166
|
- ツールを呼ぶ
|
|
158
167
|
- ツールを呼びます
|
|
@@ -166,6 +175,10 @@ terms:
|
|
|
166
175
|
# Indirect capabilities and prerequisites; preserve their modality.
|
|
167
176
|
- したりできます
|
|
168
177
|
- することが前提です
|
|
178
|
+
# Preserve capability, distributed structure, and the responsible actor.
|
|
179
|
+
- 切り替えで扱えます
|
|
180
|
+
- 分かれて現れます
|
|
181
|
+
- 担保しなければなりません
|
|
169
182
|
# Compressed noun relationships; suggestions are not automatic replacements.
|
|
170
183
|
- 明示選択
|
|
171
184
|
- 欠落理由
|
|
@@ -218,6 +231,14 @@ terms:
|
|
|
218
231
|
verbs:
|
|
219
232
|
扱う:
|
|
220
233
|
- 扱う
|
|
234
|
+
- 扱える
|
|
235
|
+
使う:
|
|
236
|
+
- 使う
|
|
237
|
+
- 使える
|
|
238
|
+
積み重なる:
|
|
239
|
+
- 積み重なる
|
|
240
|
+
見落とす:
|
|
241
|
+
- 見落とす
|
|
221
242
|
示す:
|
|
222
243
|
- 示す
|
|
223
244
|
変わる:
|
|
@@ -321,6 +342,7 @@ sahen:
|
|
|
321
342
|
- 解消
|
|
322
343
|
- 混同
|
|
323
344
|
- 回収
|
|
345
|
+
- 開放
|
|
324
346
|
negative_only:
|
|
325
347
|
- 到達する
|
|
326
348
|
- 意味する
|
data/data/writing/ja/criteria.md
CHANGED
|
@@ -34,7 +34,9 @@ adjacent sentences.
|
|
|
34
34
|
|
|
35
35
|
## Replace abstraction with the thing being discussed
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Identify both the referent and its role before retaining an abstract term.
|
|
38
|
+
A named API, file, or command can make the referent recoverable while leaving
|
|
39
|
+
its operation vague. Inspect terms such as:
|
|
38
40
|
|
|
39
41
|
| Term | What must be identifiable |
|
|
40
42
|
| --- | --- |
|
|
@@ -49,6 +51,33 @@ Do not improve a sentence by replacing one abstraction with another. For
|
|
|
49
51
|
example, changing `費用` to `コスト` says nothing unless the sentence identifies
|
|
50
52
|
what increases.
|
|
51
53
|
|
|
54
|
+
For role metaphors such as `入口`, check whether naming the actual operation or
|
|
55
|
+
relationship gives the reader more useful information, even when the referent
|
|
56
|
+
is already clear. Consider these alternatives only when evidence supports them:
|
|
57
|
+
|
|
58
|
+
| Intended role of 入口 | More direct wording |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| Object creation | 生成API・生成メソッド, or state what the method creates |
|
|
61
|
+
| Invocation or external access | 呼び出しAPI・アクセス経路, or name the call and its operation |
|
|
62
|
+
| Configuration or prompt changes | 設定項目・上書きメソッド・コールバック・変更手段, preserving the changed scope |
|
|
63
|
+
| Command use | Name the command and the action it performs |
|
|
64
|
+
| Documentation or test references | 参照先・確認対象, or state what the document explains or test checks |
|
|
65
|
+
| Learning introduction | 導入例・理解する手がかり, supported by the example's actual content |
|
|
66
|
+
| Actual execution entry point | エントリポイント when that is the established technical role |
|
|
67
|
+
|
|
68
|
+
For example, `実行基盤を作る入口はcreate()です` can become
|
|
69
|
+
`実行基盤は生成メソッドcreate()で作ります`; `利用側の入口はinstallです` can
|
|
70
|
+
become `インストールするコマンドはinstallです`. Keep asynchronous behavior,
|
|
71
|
+
inputs, conditions, and other facts from the surrounding passage.
|
|
72
|
+
Do not replace every `入口` with `エントリポイント`, or introduce an API,
|
|
73
|
+
mechanism, or stronger guarantee that the source does not establish. Preserve
|
|
74
|
+
negation and scope: a catalog listing does not imply an execution method exists.
|
|
75
|
+
Distinguish a public option or return field from internal state before describing
|
|
76
|
+
a change mechanism. Literal entrances and clearly established technical usage
|
|
77
|
+
can remain. For keep, explain the role and why retaining the wording serves the
|
|
78
|
+
reader better than the considered direct alternative; naming its referent alone
|
|
79
|
+
or appending the original sentence to a generic reason is insufficient.
|
|
80
|
+
|
|
52
81
|
## Give weak predicates a concrete action or consequence
|
|
53
82
|
|
|
54
83
|
Predicates such as `利用します`, `決めます`, `示します`, `扱います`, `整理します`,
|
|
@@ -76,11 +105,25 @@ For everyday verbs, identify the operation before choosing terminology:
|
|
|
76
105
|
| 設定を書く・設定を書きます | 設定を記述する・定義する for authoring a definition; 設定する for actually configuring something |
|
|
77
106
|
| 値を拾う | 取得する for retrieval; 抽出する for selection from existing data |
|
|
78
107
|
| 切り出す合図です | 切り出す目安です for a judgment criterion; シグナルです only for an actual signal |
|
|
108
|
+
| インタフェースから使えます | 利用できます when describing availability through the interface; retain the actor and capability |
|
|
109
|
+
| 拡張機構が積み重なります | 階層化されています only for established layers; スタックを構成しています only for an actual stack and its ordering |
|
|
110
|
+
| 拡張点として開放しています | 提供しています for offering an extension facility; 公開しています for exposing access, preserving any access restrictions |
|
|
111
|
+
| 自動継続を途中で切らずに一巡を追えます | 追跡できます・トレースできます when following the sequence; preserve the complete cycle and uninterrupted continuation |
|
|
112
|
+
| 再試行を見落とします | 検知漏れが生じます・捕捉漏れが発生します for a system's detection failure; 見落とすリスクがあります for a human's possible oversight |
|
|
113
|
+
| 差分を隠しすぎずに扱えます | 処理できます for processing; 制御できます only when control is available, preserving how much difference remains visible |
|
|
114
|
+
| 通知文に使っています | 用いられています when the use is the focus and the actor is recoverable; retain active voice when who uses it matters |
|
|
79
115
|
|
|
80
116
|
A familiar verb is not wrong merely because it is simple. Prefer the most direct
|
|
81
117
|
accurate verb; do not introduce jargon or claim parsing, execution, or a state
|
|
82
118
|
change that the evidence does not establish.
|
|
83
119
|
|
|
120
|
+
Layering and a stack are different structural claims. Do not infer either from
|
|
121
|
+
an accumulation metaphor alone. Tracking is more specific than confirmation;
|
|
122
|
+
retain ordering and continuity instead of shortening it to `確認できます`.
|
|
123
|
+
Distinguish an observed detection failure from a risk of human oversight: do not
|
|
124
|
+
turn a definite failure into a possibility or assign human observation to a
|
|
125
|
+
system. Active and passive voice must preserve the same actor and responsibility.
|
|
126
|
+
|
|
84
127
|
Do not choose a more impressive synonym merely to vary sentence endings. Keep
|
|
85
128
|
the technically correct verb when it names the real operation.
|
|
86
129
|
|
|
@@ -175,6 +218,16 @@ Inspect indirect predicates and author-centered emphasis as well:
|
|
|
175
218
|
|
|
176
219
|
- Simplify `無効化したりできます` to `無効化できます` when it describes a single
|
|
177
220
|
capability. Preserve `たり` when it marks a meaningful non-exhaustive list.
|
|
221
|
+
- Simplify `切り替えで扱えます` to `切り替えられます` when switching is the
|
|
222
|
+
capability itself. Preserve the subject, alternatives, and any separate
|
|
223
|
+
operation enabled by switching.
|
|
224
|
+
- For `三点に分かれて現れます`, identify what the three points represent. Use
|
|
225
|
+
`3か所に分散します` for distributed locations or `3つの要素として定義されます`
|
|
226
|
+
for defined elements only when that structure is established. Keep the count,
|
|
227
|
+
separation, and relationships; `現れます` alone loses structural information.
|
|
228
|
+
- Simplify `担保しなければなりません` to `担保が必要です` only when the guaranteed
|
|
229
|
+
property, responsible actor, and requirement remain explicit. A noun phrase
|
|
230
|
+
must not hide who must establish the guarantee or weaken an obligation.
|
|
178
231
|
- For `提供することが前提です`, identify whose prerequisite or assumption is
|
|
179
232
|
stated. Use `提供する必要があります` only when the source establishes an actual
|
|
180
233
|
requirement; do not turn an assumption into an obligation.
|
|
@@ -218,11 +271,17 @@ Review unusual translations against the actual concept:
|
|
|
218
271
|
| Wording to inspect | Context-dependent terminology |
|
|
219
272
|
| --- | --- |
|
|
220
273
|
| 木 | ツリー when referring to the data structure; keep literal trees and established mathematical usage |
|
|
274
|
+
| 拡張点 | 拡張ポイント for the specific extension location or interface; 拡張機構 for the broader mechanism only when that is the intended referent |
|
|
221
275
|
| 構築入口 | ビルドのエントリポイント only when the entry point starts a build, not object construction or initialization |
|
|
222
276
|
| 実装の読解 | コードリーディング for reading code; 実装の解析 when analysis is the actual task |
|
|
223
277
|
| エラーを回収する | エラーを捕捉する for catching; ハンドリングする for handling; preserve aggregation or collection when that is the behavior |
|
|
224
278
|
| 介入パターン | フックパターン only when a hook mechanism is established, not arbitrary human intervention |
|
|
225
279
|
|
|
280
|
+
An extension point and an extension mechanism can denote different scopes.
|
|
281
|
+
Keep `拡張点` when it is the project's established term and its referent is clear;
|
|
282
|
+
choose terminology for the actual interface or mechanism rather than replacing
|
|
283
|
+
all occurrences with a broader term.
|
|
284
|
+
|
|
226
285
|
These alternatives are not interchangeable replacements. Confirm the operation
|
|
227
286
|
and the domain's established usage from code, the glossary, or primary
|
|
228
287
|
documentation; record uncertainty rather than inventing a mechanism.
|
data/data/writing/ja/headings.md
CHANGED
|
@@ -17,6 +17,14 @@ Preserve conditions, negation, technical distinctions and exact terminology.
|
|
|
17
17
|
If supporting body text is missing or insufficient, record needs-evidence.
|
|
18
18
|
A table of contents alone cannot establish agreement with the section body.
|
|
19
19
|
|
|
20
|
+
For a title such as `手動圧縮の入口` or `画像・分類モデルへの入口`, apply the
|
|
21
|
+
shared role-metaphor criteria to the section evidence. Consider `起動方法` or
|
|
22
|
+
`呼び出しAPI` only when that is what the body explains. Naming a subject does
|
|
23
|
+
not by itself explain the operation. If a better title would change a generated
|
|
24
|
+
section ID, use the exact permitted_id_anchor only when the saved session explicitly
|
|
25
|
+
authorizes it. Otherwise record the proposed title and ID concern for separate
|
|
26
|
+
authorized preservation. Protection does not justify an editorial keep decision.
|
|
27
|
+
|
|
20
28
|
## Compare headings with the same role
|
|
21
29
|
|
|
22
30
|
Read the complete outline and compare parent, sibling and child headings.
|
data/lib/asciidoc_pubkit/cli.rb
CHANGED
|
@@ -8,7 +8,7 @@ module AsciidocPubkit
|
|
|
8
8
|
Commands:
|
|
9
9
|
writing criteria Print the shared Japanese prose criteria
|
|
10
10
|
writing prompt Generate a Japanese technical writing prompt
|
|
11
|
-
review scan FILE Collect Japanese prose or
|
|
11
|
+
review scan FILE Collect Japanese prose, headings, or list text and review candidates
|
|
12
12
|
review score FILE Score Japanese prose; optionally use a local AI CLI
|
|
13
13
|
review prompt SESSION Generate an English review prompt with Japanese source excerpts
|
|
14
14
|
review verify SESSION Compare edited sources with the saved baseline
|
|
@@ -45,7 +45,7 @@ module AsciidocPubkit
|
|
|
45
45
|
parser = OptionParser.new do |opts|
|
|
46
46
|
input_name = group == 'writing' ? '' : ((group == 'replace' || %w[scan score].include?(command)) ? ' FILE' : ' SESSION')
|
|
47
47
|
opts.banner = "Usage: asciidoc-pubkit #{group} #{command} [options]#{input_name}"
|
|
48
|
-
opts.on('-o', '--output PATH', group == 'review' && command == 'scan' ? 'New session directory (default: .pubkit/review
|
|
48
|
+
opts.on('-o', '--output PATH', group == 'review' && command == 'scan' ? 'New session directory (default: .pubkit/review, .pubkit/headings, or .pubkit/lists)' : 'New output file (default: standard output)') { |v| options[:output] = v }
|
|
49
49
|
opts.on('--lang LANG', 'Language (ja only in this release)') { |v| options[:language] = v }
|
|
50
50
|
if group == 'replace'
|
|
51
51
|
opts.on('--rules FILE', 'Required prh-format replacement rules (limited compatibility)') { |v| options[:rules] = v }
|
|
@@ -54,7 +54,8 @@ module AsciidocPubkit
|
|
|
54
54
|
opts.on('--only FILE', 'Select one included file') { |v| options[:only] = v }
|
|
55
55
|
elsif group == 'review' && %w[scan score].include?(command)
|
|
56
56
|
if command == 'scan'
|
|
57
|
-
opts.on('--scope SCOPE', 'prose (default) or
|
|
57
|
+
opts.on('--scope SCOPE', 'prose (default), headings, or lists; separate review sessions') { |v| options[:scope] = v }
|
|
58
|
+
opts.on('--preserve-heading-ids', 'Allow exact old-ID anchors before eligible headings') { options[:preserve_heading_ids] = true }
|
|
58
59
|
opts.on('--heading-rules FILE', 'Replace default heading rules with a YAML rule set') { |v| options[:heading_rules] = v }
|
|
59
60
|
opts.on('-y', '--yes', 'Answer yes to replacement confirmation') { options[:yes] = true }
|
|
60
61
|
opts.on('--no-input', 'Never prompt; fail on existing output unless --yes') { options[:no_input] = true }
|
|
@@ -128,6 +129,8 @@ module AsciidocPubkit
|
|
|
128
129
|
end
|
|
129
130
|
if result['scope'] == 'headings'
|
|
130
131
|
out.puts "Scanned #{result['headings']} headings; found #{result['findings']} review candidates."
|
|
132
|
+
elsif result['scope'] == 'lists'
|
|
133
|
+
out.puts "Scanned #{result['paragraphs']} list items; found #{result['findings']} review candidates."
|
|
131
134
|
else
|
|
132
135
|
out.puts "Scanned #{result['paragraphs']} paragraphs; found #{result['findings']} review candidates."
|
|
133
136
|
end
|
|
@@ -64,6 +64,15 @@ module AsciidocPubkit
|
|
|
64
64
|
true
|
|
65
65
|
end
|
|
66
66
|
nodes.each { |node| collect(node) }
|
|
67
|
+
if scope == 'lists'
|
|
68
|
+
reused = @paragraphs.group_by { |p| [p['file'], p['line']] }.select { |_, group| group.length > 1 }
|
|
69
|
+
@paragraphs.reject! do |paragraph|
|
|
70
|
+
next false unless reused.key?([paragraph['file'], paragraph['line']])
|
|
71
|
+
@coverage << { 'context' => 'list_item', 'file' => paragraph['file'], 'line' => paragraph['line'],
|
|
72
|
+
'reason' => 'The source list item is reused and cannot be edited independently.' }
|
|
73
|
+
true
|
|
74
|
+
end
|
|
75
|
+
end
|
|
67
76
|
ensure
|
|
68
77
|
Asciidoctor::LoggerManager.logger = previous_logger
|
|
69
78
|
end
|
|
@@ -110,14 +119,80 @@ module AsciidocPubkit
|
|
|
110
119
|
@coverage << { 'context' => 'heading', 'file' => path, 'line' => line, 'reason' => 'Excluded by configuration.' }
|
|
111
120
|
return
|
|
112
121
|
end
|
|
122
|
+
section_id = node.id
|
|
123
|
+
generated = section_id && !node.attributes.key?('id')
|
|
124
|
+
anchor = if @settings['preserve_heading_ids'] && generated && section_id.match?(/\A[\p{L}\p{N}_.:-]+\z/)
|
|
125
|
+
"[##{section_id}]"
|
|
126
|
+
end
|
|
113
127
|
@headings << { 'id' => AsciidocPubkit.hash_text([path, line, match[2]].join("\0"))[0, 16],
|
|
114
128
|
'index' => index, 'parent_index' => parent_index,
|
|
115
129
|
'file' => path, 'line' => line, 'column' => match[1].length + 1,
|
|
116
130
|
'prefix' => match[1], 'suffix' => match[3], 'level' => node.level,
|
|
117
|
-
'section_id' =>
|
|
131
|
+
'section_id' => section_id, 'id_generated' => !!generated, 'permitted_id_anchor' => anchor, 'text' => match[2] }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def collect_list_item(node)
|
|
135
|
+
cursor = node.source_location
|
|
136
|
+
path, line = cursor && [cursor.file, cursor.lineno]
|
|
137
|
+
parent = node.parent
|
|
138
|
+
supported = %i[ulist olist].include?(parent.context)
|
|
139
|
+
while parent
|
|
140
|
+
supported = false if %i[quote verse table listing literal pass dlist colist].include?(parent.context)
|
|
141
|
+
parent = parent.parent
|
|
142
|
+
end
|
|
143
|
+
# ListItem#text applies substitutions; read through the public subs API.
|
|
144
|
+
original_subs = node.subs.dup
|
|
145
|
+
begin
|
|
146
|
+
node.subs.clear
|
|
147
|
+
text = node.text
|
|
148
|
+
ensure
|
|
149
|
+
node.subs.replace(original_subs)
|
|
150
|
+
end
|
|
151
|
+
raw = path && @source_lines[path] && @source_lines[path][line - 1]
|
|
152
|
+
pattern = node.marker && /\A([ \t]*#{Regexp.escape(node.marker)}[ \t]+)(.*?)([ \t]*)\z/
|
|
153
|
+
match = raw && pattern && raw.match(pattern)
|
|
154
|
+
# Include boundaries can leave the cursor on the include directive.
|
|
155
|
+
# Recover a unique physical span; repeated use is rejected after collection.
|
|
156
|
+
if supported && node.simple? && text && !text.include?("\n") && pattern && (!match || match[2] != text)
|
|
157
|
+
candidates = @source_lines.flat_map do |source_path, lines|
|
|
158
|
+
lines.each_with_index.filter_map do |source_line, offset|
|
|
159
|
+
candidate = source_line.match(pattern)
|
|
160
|
+
[source_path, offset + 1, candidate] if candidate && candidate[2] == text
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
path, line, match = candidates.first if candidates.length == 1
|
|
164
|
+
end
|
|
165
|
+
unless supported && node.simple? && text && !text.include?("\n") && match && match[2] == text && !text.empty?
|
|
166
|
+
@coverage << { 'context' => 'list_item', 'file' => path, 'line' => line,
|
|
167
|
+
'reason' => 'Only unambiguously mapped, single-line outline list text with simple content is editable.' }
|
|
168
|
+
return
|
|
169
|
+
end
|
|
170
|
+
return if @only && @only != path
|
|
171
|
+
relative = Pathname.new(path).relative_path_from(Pathname.new(@root)).to_s
|
|
172
|
+
return if @settings.fetch('exclude').any? { |glob| File.fnmatch?(glob, relative, File::FNM_PATHNAME | File::FNM_DOTMATCH) }
|
|
173
|
+
headings = []
|
|
174
|
+
section_index = nil
|
|
175
|
+
parent = node.parent
|
|
176
|
+
while parent
|
|
177
|
+
if parent.context == :section && parent.title
|
|
178
|
+
headings.unshift(parent.title)
|
|
179
|
+
section_index ||= @section_indexes[parent]
|
|
180
|
+
end
|
|
181
|
+
parent = parent.parent
|
|
182
|
+
end
|
|
183
|
+
@paragraphs << {
|
|
184
|
+
'id' => AsciidocPubkit.hash_text([path, line, text].join("\0"))[0, 16],
|
|
185
|
+
'file' => path, 'line' => line, 'end_line' => line, 'column' => match[1].length + 1,
|
|
186
|
+
'prefix' => match[1], 'suffix' => match[3], 'kind' => 'list-item',
|
|
187
|
+
'section_index' => section_index, 'headings' => headings, 'text' => text
|
|
188
|
+
}
|
|
118
189
|
end
|
|
119
190
|
|
|
120
191
|
def collect(node)
|
|
192
|
+
if scope == 'lists'
|
|
193
|
+
collect_list_item(node) if node.context == :list_item
|
|
194
|
+
return
|
|
195
|
+
end
|
|
121
196
|
if %i[list_item table quote verse listing literal pass].include?(node.context)
|
|
122
197
|
@coverage << { 'context' => node.context.to_s, 'reason' => 'Not reviewed as running prose.' }
|
|
123
198
|
end
|
|
@@ -213,7 +213,7 @@ module AsciidocPubkit
|
|
|
213
213
|
'id' => AsciidocPubkit.hash_text([paragraph['id'], rule, offset, match].join(':'))[0, 16],
|
|
214
214
|
'paragraph_id' => paragraph['id'], 'rule' => rule, 'severity' => severity,
|
|
215
215
|
'file' => paragraph['file'], 'line' => paragraph['line'] + prefix.count("\n"),
|
|
216
|
-
'column' => (prefix.rindex("\n") ? prefix.length - prefix.rindex("\n") : prefix.length + 1),
|
|
216
|
+
'column' => (prefix.rindex("\n") ? prefix.length - prefix.rindex("\n") : prefix.length + paragraph.fetch('column', 1)),
|
|
217
217
|
'match' => match, 'question' => question
|
|
218
218
|
}
|
|
219
219
|
end
|
|
@@ -4,7 +4,7 @@ require 'tmpdir'
|
|
|
4
4
|
|
|
5
5
|
module AsciidocPubkit
|
|
6
6
|
class Session
|
|
7
|
-
SCHEMA =
|
|
7
|
+
SCHEMA = 3
|
|
8
8
|
|
|
9
9
|
def self.scan(entry, options)
|
|
10
10
|
settings = Settings.new(entry, options)
|
|
@@ -12,7 +12,7 @@ module AsciidocPubkit
|
|
|
12
12
|
unless document.diagnostics.empty?
|
|
13
13
|
raise Error, "Document diagnostics must be resolved before scanning:\n" + document.diagnostics.map { |d| "#{d['severity']}: #{d['message']}" }.join("\n")
|
|
14
14
|
end
|
|
15
|
-
default_output =
|
|
15
|
+
default_output = { 'headings' => '.pubkit/headings', 'lists' => '.pubkit/lists' }.fetch(settings.data['scope'], '.pubkit/review')
|
|
16
16
|
destination = File.expand_path(options.fetch(:output, default_output))
|
|
17
17
|
replacing = File.exist?(destination) || File.symlink?(destination)
|
|
18
18
|
if replacing
|
|
@@ -95,13 +95,18 @@ module AsciidocPubkit
|
|
|
95
95
|
File.write(path, JSON.pretty_generate(value) + "\n")
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
def self.protected_content(document)
|
|
98
|
+
def self.protected_content(document, allowed_anchor_lines: {})
|
|
99
99
|
document.sources.to_h do |path, raw|
|
|
100
100
|
paragraphs = document.paragraphs.select { |p| p['file'] == path }
|
|
101
101
|
heading_scope = document.scope == 'headings'
|
|
102
102
|
editable_headings = document.headings.select { |h| h['file'] == path }.to_h { |h| [h['line'], h] }
|
|
103
|
+
editable_items = document.scope == 'lists' ? paragraphs.to_h { |p| [p['line'], p] } : {}
|
|
103
104
|
editable_lines = heading_scope ? [] : paragraphs.flat_map { |p| (p['line']..p['end_line']).to_a }
|
|
104
105
|
outside = raw.lines.each_with_index.filter_map do |line, index|
|
|
106
|
+
next if allowed_anchor_lines.fetch(path, []).include?(index + 1)
|
|
107
|
+
if (item = editable_items[index + 1])
|
|
108
|
+
next [item['prefix'], '<editable-list-text>', item['suffix']]
|
|
109
|
+
end
|
|
105
110
|
next if editable_lines.include?(index + 1)
|
|
106
111
|
if heading_scope && (heading = editable_headings[index + 1])
|
|
107
112
|
# Keep a positional placeholder: removing entire lines would hide reordering.
|
|
@@ -160,6 +165,7 @@ module AsciidocPubkit
|
|
|
160
165
|
raise Error, 'Sources have changed since scanning. Create a new scan before generating a prompt.' unless stale.empty?
|
|
161
166
|
language = Language.validate!(@manifest.fetch('settings').fetch('language'), operation: 'review')
|
|
162
167
|
return heading_prompt(mode, language) if @manifest.fetch('settings').fetch('scope', 'prose') == 'headings'
|
|
168
|
+
list_scope = @manifest['settings']['scope'] == 'lists'
|
|
163
169
|
criteria = @manifest.fetch('writing_criteria')
|
|
164
170
|
instructions = <<~TEXT
|
|
165
171
|
# Japanese manuscript review
|
|
@@ -184,7 +190,7 @@ module AsciidocPubkit
|
|
|
184
190
|
After editing, reread each paragraph in context. Report unresolved issues and do not claim publication readiness.
|
|
185
191
|
Mechanical verification does not establish semantic correctness.
|
|
186
192
|
|
|
187
|
-
#{review_process('paragraph', mode)}
|
|
193
|
+
#{review_process(list_scope ? 'list item' : 'paragraph', mode)}
|
|
188
194
|
|
|
189
195
|
## Shared prose criteria
|
|
190
196
|
|
|
@@ -213,6 +219,18 @@ module AsciidocPubkit
|
|
|
213
219
|
Coverage notices: #{@document['coverage'].length}
|
|
214
220
|
|
|
215
221
|
TEXT
|
|
222
|
+
if list_scope
|
|
223
|
+
instructions.sub!('running-prose paragraphs', 'single-line outline list item text')
|
|
224
|
+
instructions.sub!('proposed paragraph revisions', 'proposed list item revisions')
|
|
225
|
+
instructions.sub!('Do not change excluded content, lists, tables, quotations, or other files.',
|
|
226
|
+
'Preserve list markers, nesting, order, continuation syntax, and inline tokens. Do not edit running prose, excluded list items, tables, quotations, or other files.')
|
|
227
|
+
instructions.sub!('running-prose edit scope', 'selected list-text edit scope')
|
|
228
|
+
instructions.sub!('Only source-mapped running-prose paragraphs are reviewed.', 'Only unambiguously source-mapped, single-line simple unordered or ordered list text is reviewed.')
|
|
229
|
+
instructions.sub!('Headings, lists, tables, quotations, code, and passthrough blocks are not prose-reviewed in this release.',
|
|
230
|
+
'Multiline, description, checklist, compound, and reused-source list items remain protected. Running prose, headings, tables, quotations, code, and passthrough blocks are not reviewed in this session.')
|
|
231
|
+
instructions.sub!('the supplied prose/body context omits lists and other excluded blocks',
|
|
232
|
+
'this session supplies only selected list text and heading labels; running prose and other excluded blocks are omitted')
|
|
233
|
+
end
|
|
216
234
|
instructions << <<~TEXT
|
|
217
235
|
## Reading order
|
|
218
236
|
|
|
@@ -232,7 +250,7 @@ module AsciidocPubkit
|
|
|
232
250
|
instructions << "## Context\n\n#{prompt_data(JSON.generate(context), 'json')}\n"
|
|
233
251
|
previous_context = context
|
|
234
252
|
end
|
|
235
|
-
instructions << "### Paragraph #{paragraph['id']} — lines #{paragraph['line']}–#{paragraph['end_line']}\n\n"
|
|
253
|
+
instructions << "### #{list_scope ? 'List item' : 'Paragraph'} #{paragraph['id']} — lines #{paragraph['line']}–#{paragraph['end_line']}\n\n"
|
|
236
254
|
instructions << prompt_data(paragraph['text'], 'text') << "\n"
|
|
237
255
|
related = findings_by_paragraph.fetch(paragraph['id'], [])
|
|
238
256
|
if related.empty?
|
|
@@ -252,7 +270,7 @@ module AsciidocPubkit
|
|
|
252
270
|
document.diagnostics.each { |d| issues << { 'kind' => 'parse-diagnostic', 'message' => d['message'] } }
|
|
253
271
|
old_paths = @manifest['sources'].map { |source| source['path'] }.sort
|
|
254
272
|
issues << { 'kind' => 'source-set-changed', 'message' => 'The included source file set changed.' } if old_paths != document.sources.keys.sort
|
|
255
|
-
current = self.class.protected_content(document)
|
|
273
|
+
current = self.class.protected_content(document, allowed_anchor_lines: permitted_anchor_lines(document))
|
|
256
274
|
@manifest['protected'].each do |path, saved|
|
|
257
275
|
next if current[path] == saved
|
|
258
276
|
issues << { 'kind' => 'protected-content-changed', 'file' => path,
|
|
@@ -288,6 +306,21 @@ module AsciidocPubkit
|
|
|
288
306
|
|
|
289
307
|
private
|
|
290
308
|
|
|
309
|
+
def permitted_anchor_lines(document)
|
|
310
|
+
return {} unless @manifest['settings']['scope'] == 'headings' && @manifest['settings']['preserve_heading_ids']
|
|
311
|
+
allowed = Hash.new { |hash, path| hash[path] = [] }
|
|
312
|
+
@document.fetch('headings', []).each do |saved|
|
|
313
|
+
anchor = saved['permitted_id_anchor']
|
|
314
|
+
next unless anchor
|
|
315
|
+
current = document.headings.find { |heading| heading['index'] == saved['index'] && heading['file'] == saved['file'] }
|
|
316
|
+
next unless current && current['section_id'] == saved['section_id']
|
|
317
|
+
line = current['line'] - 1
|
|
318
|
+
next unless line.positive? && document.sources.fetch(current['file']).lines[line - 1].chomp == anchor
|
|
319
|
+
allowed[current['file']] << line
|
|
320
|
+
end
|
|
321
|
+
allowed
|
|
322
|
+
end
|
|
323
|
+
|
|
291
324
|
def comparison_structure(structure, headings, heading_scope)
|
|
292
325
|
editable = headings.map { |h| h['index'] }
|
|
293
326
|
structure.each_with_index.filter_map do |node, index|
|
|
@@ -311,7 +344,11 @@ module AsciidocPubkit
|
|
|
311
344
|
Preserve section count, order, hierarchy, IDs, references, attributes, include directives,
|
|
312
345
|
inline tokens, title markers, and all content outside the selected title spans.
|
|
313
346
|
Title-derived section IDs can change after a title edit. Keep IDs unchanged;
|
|
314
|
-
|
|
347
|
+
when permitted_id_anchor is present in the saved heading metadata, you may insert
|
|
348
|
+
that exact anchor on the line immediately before its heading to preserve the old ID.
|
|
349
|
+
This is the only authorized addition outside title spans. Do not edit existing anchors,
|
|
350
|
+
invent IDs, or add anchors for other headings. Without that permission, report the
|
|
351
|
+
concern and leave the title for a separately authorized ID preservation task.
|
|
315
352
|
Preserve the configured fixed section names; do not rename them merely for variety.
|
|
316
353
|
Automated findings are review candidates, not proven defects.
|
|
317
354
|
Do not invent facts, guarantees, implementation mechanisms or benefits.
|
|
@@ -343,7 +380,8 @@ module AsciidocPubkit
|
|
|
343
380
|
|
|
344
381
|
## Coverage and reading order
|
|
345
382
|
|
|
346
|
-
Only selected, unambiguously source-mapped plain ATX section titles
|
|
383
|
+
Only selected, unambiguously source-mapped plain ATX section titles and explicitly
|
|
384
|
+
permitted old-ID anchor additions are editable.
|
|
347
385
|
Document titles, old-style headings, converted inline titles and attribute-expanded
|
|
348
386
|
titles remain protected. Body coverage excludes lists, tables, quotations and code;
|
|
349
387
|
use needs-evidence when the supplied body cannot establish a title's scope.
|
|
@@ -381,11 +419,13 @@ module AsciidocPubkit
|
|
|
381
419
|
## Review decisions and completion
|
|
382
420
|
|
|
383
421
|
Keep manifest.json, document.json, findings.json, and every baseline/ snapshot immutable. Restrict editing and formatting tools to the authorized source spans; never run them over the session directory.
|
|
384
|
-
|
|
422
|
+
Check mechanical preservation and baseline integrity with this session before editing and at completion. If a baseline or artifact integrity check fails, stop editing, preserve the evidence, and report the failure. Do not repair or overwrite snapshots, update their hashes, or replace the session to turn a failed check into a successful report; a fresh scan cannot prove preservation against the original baseline.
|
|
423
|
+
Record each reviewed #{unit} ID and each candidate ID with revise, keep, or needs-evidence and a reason grounded in that passage. For keep, identify the concrete referent, operation, condition, necessary distinction, or established terminology that justifies retaining it. A shared generic reason does not establish individual review. Appending a source quotation to a stock reason is still insufficient.
|
|
424
|
+
For each candidate decision, identify its concrete role or claim, the evidence and source location, the direct wording considered, and why that alternative is better or why the original wording is necessary. For needs-evidence, name the missing support instead of inventing a role or revision. A quotation supports evidence but does not substitute for that explanation. For role metaphors such as 入口, apply the shared criteria even when a nearby identifier makes the referent clear.
|
|
385
425
|
Never infer revise or keep from whether the matched string survives, disappears, or changes. Do not bulk-assign keep to unchanged #{unit}s or remaining candidates. An unreviewed item stays pending; use needs-evidence only after review identifies missing evidence.
|
|
386
426
|
Review #{unit}s without candidates against the shared criteria as well. For concerns outside the editable scope, report the location and a separate out-of-scope proposal; do not count protection as an editorial keep decision or edit protected content.
|
|
387
427
|
#{mode == 'revise' ? 'Compare the original and edited passages, check both information loss and unsupported additions, and reconcile each recorded decision with the actual diff. After verification, individually inspect newly detected or remaining candidates; retain the original candidate IDs in the review record.' : 'Compare each proposed revision with the original passage for information loss and unsupported additions. A revise decision means a proposed revision, not an applied edit.'}
|
|
388
|
-
Report mechanical preservation, candidate decisions, and #{unit}-level quality review separately. State selected and reviewed #{unit} counts, candidate decision counts, pending items, needs-evidence items, out-of-scope concerns, and evidence used. If any selected item or candidate remains pending, report the review as incomplete.
|
|
428
|
+
Report mechanical preservation, candidate decisions, and #{unit}-level quality review separately. State selected and reviewed #{unit} counts, candidate decision counts, pending items, needs-evidence items, out-of-scope concerns, and evidence used. Recheck retained role metaphors by their actual roles and cite the individual decisions; listing remaining words is not enough. Out-of-scope concerns cover only evidence actually inspected; the supplied prose/body context omits lists and other excluded blocks, so do not claim those were reviewed. If any selected item or candidate remains pending, report the review as incomplete.
|
|
389
429
|
Mechanical verification does not read or validate these decision records. Its passed result and candidate counts do not establish review completion or writing quality; meaning_verified remains false. Do not claim semantic correctness from those checks.
|
|
390
430
|
TEXT
|
|
391
431
|
end
|
|
@@ -31,20 +31,24 @@ module AsciidocPubkit
|
|
|
31
31
|
base = @path ? File.dirname(@path) : File.dirname(File.expand_path(entry))
|
|
32
32
|
language = Language.validate!(options[:language] || review.fetch('language', Language::DEFAULT), operation: 'review')
|
|
33
33
|
scope = options.fetch(:scope, 'prose')
|
|
34
|
-
raise Error, 'scope must be prose or
|
|
34
|
+
raise Error, 'scope must be prose, headings, or lists.' unless %w[prose headings lists].include?(scope)
|
|
35
35
|
if scope == 'headings' && (options[:rules] || options[:style])
|
|
36
36
|
raise Error, 'Heading scans use --heading-rules, not prose --rules or --style.'
|
|
37
37
|
end
|
|
38
|
-
if scope
|
|
38
|
+
if scope != 'headings' && options[:preserve_heading_ids]
|
|
39
|
+
raise Error, '--preserve-heading-ids requires --scope headings.'
|
|
40
|
+
end
|
|
41
|
+
if scope != 'headings' && options[:heading_rules]
|
|
39
42
|
raise Error, '--heading-rules requires --scope headings.'
|
|
40
43
|
end
|
|
41
44
|
heading_rules_path = options[:heading_rules] ? File.expand_path(options[:heading_rules]) : (review['heading_rules'] ? File.expand_path(review['heading_rules'], base) : HeadingRuleSet.default_path(language))
|
|
42
45
|
rules_path = options[:replacement] ? RuleSet.default_path(language) : options[:rules] ? File.expand_path(options[:rules]) : (review['rules'] ? File.expand_path(review['rules'], base) : RuleSet.default_path(language))
|
|
43
46
|
@data = {
|
|
44
47
|
'scope' => scope,
|
|
48
|
+
'preserve_heading_ids' => !!options[:preserve_heading_ids],
|
|
45
49
|
'heading_rules' => scope == 'headings' ? HeadingRuleSet.load(heading_rules_path) : nil,
|
|
46
50
|
'heading_rules_path' => heading_rules_path,
|
|
47
|
-
'rules' => scope
|
|
51
|
+
'rules' => scope != 'headings' ? RuleSet.load(rules_path) : nil,
|
|
48
52
|
'rules_path' => rules_path,
|
|
49
53
|
'language' => language,
|
|
50
54
|
'style' => options[:style] || review.fetch('style', 'preserve'),
|
data/lib/asciidoc_pubkit.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: asciidoc-pubkit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- CyberGarage
|
|
@@ -37,8 +37,8 @@ dependencies:
|
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '1.0'
|
|
40
|
-
description: Generate Japanese technical writing prompts, review AsciiDoc prose
|
|
41
|
-
|
|
40
|
+
description: Generate Japanese technical writing prompts, review AsciiDoc prose, section
|
|
41
|
+
headings, and list text separately, verify protected manuscript content, and explicitly
|
|
42
42
|
apply prose-only mechanical replacements.
|
|
43
43
|
executables:
|
|
44
44
|
- asciidoc-pubkit
|