asciidoc-pubkit 0.9.0 → 1.0.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/CHANGELOG.md +33 -0
- data/README.md +96 -1495
- data/data/writing/ja/criteria.md +53 -0
- data/docs/architecture.md +264 -0
- data/docs/configuration.md +48 -0
- data/docs/custom-rules.md +69 -0
- data/docs/development.md +23 -0
- data/docs/document-commands.md +68 -0
- data/docs/english-review-research.md +314 -0
- data/docs/installation.md +134 -0
- data/docs/list-review.md +50 -0
- data/docs/prose-evaluation.md +246 -0
- data/docs/references.md +54 -0
- data/docs/replacements.md +193 -0
- data/docs/review-workflow.md +267 -0
- data/docs/rules-and-coverage.md +158 -0
- data/docs/scoring.md +37 -0
- data/docs/writing.md +33 -0
- data/lib/asciidoc_pubkit.rb +1 -1
- metadata +16 -1
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Prose evaluation
|
|
2
|
+
|
|
3
|
+
Use a fixed set of Japanese technical paragraphs to compare detector or review
|
|
4
|
+
criteria changes against a project-defined baseline. Keep detection performance,
|
|
5
|
+
readability, and meaning preservation separate so that a clearer rewrite cannot
|
|
6
|
+
hide a lost condition or invented fact.
|
|
7
|
+
|
|
8
|
+
This guide describes the version 1.0.1 development checkout, including the
|
|
9
|
+
`technical-prose-v2` corpus and criteria update. The evaluation runner is not an
|
|
10
|
+
installed gem command. It does not measure Japanese naturalness or AI authorship
|
|
11
|
+
as a single validated score.
|
|
12
|
+
|
|
13
|
+
## Three different evaluations
|
|
14
|
+
|
|
15
|
+
| Evaluation | Input and method | What the number means |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| `review score` without `--agent` | A manuscript; candidate count normalized by unmasked prose length | Candidate-density indicator, not correctness or naturalness |
|
|
18
|
+
| `script/evaluate-prose` without `--agent` | Fixed corpus and annotated targets; deterministic analysis | Detector precision, recall, F1, and location accuracy |
|
|
19
|
+
| `script/evaluate-prose --agent codex` or `--agent claude` | Fixed corpus; generated review prompt, rewrite, and separate judge invocation | Readability and checklist preservation before and after rewriting |
|
|
20
|
+
|
|
21
|
+
The default manuscript score is `max(0, 100 - 5 × candidates per 1,000 characters)`.
|
|
22
|
+
A higher score means fewer detected candidates at that text length. Necessary
|
|
23
|
+
repetition can still be a candidate, and fewer candidates alone do not establish
|
|
24
|
+
better prose. See [Manuscript scoring](scoring.md) for the separate optional
|
|
25
|
+
single-manuscript readability rating; that path has no original-versus-revision
|
|
26
|
+
fact checklist.
|
|
27
|
+
|
|
28
|
+
For a detector change, use the deterministic benchmark. For a writing or review
|
|
29
|
+
criteria change, use the optional rewrite-and-judge trials to measure its effect
|
|
30
|
+
on the actual revisions. Criteria can change while deterministic detector scores
|
|
31
|
+
remain identical.
|
|
32
|
+
|
|
33
|
+
## Fixed test data
|
|
34
|
+
|
|
35
|
+
All examples are original project-authored editorial fixtures. They intentionally
|
|
36
|
+
include patterns associated with generated prose, plus valid technical controls.
|
|
37
|
+
They are not a collected dataset of known AI outputs or a representative sample
|
|
38
|
+
of Japanese writing.
|
|
39
|
+
|
|
40
|
+
| File | Contents and role |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| [prose_benchmark.ja.adoc](../test/fixtures/prose_benchmark.ja.adoc) | 21 paragraphs used as the actual AsciiDoc input |
|
|
43
|
+
| [prose_benchmark.ja.json](../test/fixtures/prose_benchmark.ja.json) | Matching paragraph IDs and text, 11 annotated detector targets, and preservation checklists |
|
|
44
|
+
| [prose_benchmark.yml](../test/fixtures/prose_benchmark.yml) | Fixed empty configuration that isolates the benchmark from discovered manuscript settings |
|
|
45
|
+
| [prose_evaluation.ja.json](../test/fixtures/prose_evaluation.ja.json) | Detection examples and 20 manual revision pairs with expected `accept`, `reject`, or `needs-evidence` dispositions |
|
|
46
|
+
|
|
47
|
+
The corpus includes framing such as `重要なのは`, metaphorical operations such
|
|
48
|
+
as `地味に効く`, inflected and negative forms, and repeated endings. Controls
|
|
49
|
+
include literal verbs, established technical terms, necessary repetition,
|
|
50
|
+
concurrency requirements, and protected inline code.
|
|
51
|
+
|
|
52
|
+
Eight paragraphs added in `technical-prose-v2` cover quantity targets, required
|
|
53
|
+
order, modifier targets, condition scope, parallel checks, advice versus actual
|
|
54
|
+
behavior, plain style, and punctuation and purpose scope. They have no additional
|
|
55
|
+
detector targets but still reach the reviewer and judge. The checklists include
|
|
56
|
+
explicit editorial constraints as well as technical facts.
|
|
57
|
+
|
|
58
|
+
For example, this pair must be rejected even though its numeral is unchanged:
|
|
59
|
+
|
|
60
|
+
| Original | Revision | Preservation issue |
|
|
61
|
+
| --- | --- | --- |
|
|
62
|
+
| 各ワーカーは最大3回再試行します。 | 全ワーカーで合計3回まで再試行します。 | A per-worker limit became an aggregate limit |
|
|
63
|
+
|
|
64
|
+
Other revision pairs cover reversed recovery order, authentication conditions
|
|
65
|
+
incorrectly extended to audit logging, independent checks made conditional, and
|
|
66
|
+
an unsolicited change from plain to polite style. Acceptable pairs and unresolved
|
|
67
|
+
cases prevent calibration from treating every change as an error.
|
|
68
|
+
|
|
69
|
+
## What normal tests check
|
|
70
|
+
|
|
71
|
+
Run the complete suite from the repository root with MeCab and UTF-8 IPADIC
|
|
72
|
+
installed:
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
bundle exec rake test
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
[Prose benchmark tests](../test/prose_benchmark_test.rb) check exact agreement
|
|
79
|
+
between the AsciiDoc input and JSON corpus, source mapping and paragraph order,
|
|
80
|
+
annotated target positions, false positives and duplicates, and both MeCab and
|
|
81
|
+
explicit literal analysis. They also check response validation, comparison
|
|
82
|
+
compatibility, summary calculations, and mechanical verification in a trial
|
|
83
|
+
using a fake evaluator. The fake evaluator makes the workflow test repeatable;
|
|
84
|
+
it does not assess readability or understand the revision pairs.
|
|
85
|
+
|
|
86
|
+
[Default rule tests](../test/default_rules_test.rb) check metaphor detection,
|
|
87
|
+
allow lists, and protected text using the detection examples.
|
|
88
|
+
[Writing tests](../test/writing_test.rb) and
|
|
89
|
+
[review tests](../test/review_test.rb) check that the shared criteria reach writing
|
|
90
|
+
prompts and saved review prompts. Existing sessions retain their saved criteria.
|
|
91
|
+
|
|
92
|
+
Normal tests never invoke Codex or Claude. A passing suite establishes these
|
|
93
|
+
contracts and regressions, not a measured improvement in model-generated prose.
|
|
94
|
+
Literal-mode checks do not validate MeCab; there is no automatic fallback.
|
|
95
|
+
|
|
96
|
+
## Establish a detector baseline
|
|
97
|
+
|
|
98
|
+
Before changing the detector or review criteria, save a result on the fixed
|
|
99
|
+
corpus. After the change, use a new output directory and compare it:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
bundle exec ruby script/evaluate-prose --output .pubkit/evaluation/before
|
|
103
|
+
# After changing the detector or review criteria:
|
|
104
|
+
bundle exec ruby script/evaluate-prose --output .pubkit/evaluation/after \
|
|
105
|
+
--compare .pubkit/evaluation/before/report.json
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The report scores only `generic-framing`, the four metaphorical-operation
|
|
109
|
+
patterns, and `repeated-ending`. Other rule findings are counted separately.
|
|
110
|
+
Detection matches a target's paragraph and kind. Location accuracy then checks
|
|
111
|
+
its exact Unicode character offset; CLI source columns are one-based. A repeated
|
|
112
|
+
ending target is at the matching ending of the third consecutive sentence.
|
|
113
|
+
|
|
114
|
+
| Report field | Definition |
|
|
115
|
+
| --- | --- |
|
|
116
|
+
| `detection.precision` | Matched targets divided by detected scored candidates, × 100 |
|
|
117
|
+
| `detection.recall` | Matched targets divided by annotated targets, × 100 |
|
|
118
|
+
| `detection.f1` | 2 × matched targets divided by the sum of detected and annotated counts, × 100 |
|
|
119
|
+
| `detection.location_accuracy` | Correctly located matches divided by all matched targets, × 100 |
|
|
120
|
+
| `detection_delta` | After minus before for these four metrics, in percentage points |
|
|
121
|
+
|
|
122
|
+
Duplicate detections count as false positives. Zero denominators are `null`, not
|
|
123
|
+
perfect scores. A correctly detected candidate can still deserve a `keep`
|
|
124
|
+
decision in contextual review.
|
|
125
|
+
|
|
126
|
+
The historical [MeCab baseline](../benchmark/baseline-mecab.json) belongs to the
|
|
127
|
+
original 13-paragraph `technical-prose-v1` corpus. Its precision was 100, recall
|
|
128
|
+
81.818, F1 90, and location accuracy 77.778. Later detector fixes brought the
|
|
129
|
+
11-target MeCab results to 100 for all four metrics; literal recall remained
|
|
130
|
+
81.818. Keep that historical report unchanged. It cannot be compared directly
|
|
131
|
+
with v2: create a new baseline after expanding the corpus.
|
|
132
|
+
|
|
133
|
+
## Compare review criteria with AI trials
|
|
134
|
+
|
|
135
|
+
First fix the corpus, calibration pairs, and judge rubric. Save an AI baseline
|
|
136
|
+
before changing the review criteria, then change only the intended criteria and
|
|
137
|
+
rerun under the same conditions:
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
bundle exec ruby script/evaluate-prose --agent codex --repeats 3 \
|
|
141
|
+
--output .pubkit/evaluation/ai-before
|
|
142
|
+
# After changing only the review criteria:
|
|
143
|
+
bundle exec ruby script/evaluate-prose --agent codex --repeats 3 \
|
|
144
|
+
--output .pubkit/evaluation/ai-after \
|
|
145
|
+
--compare .pubkit/evaluation/ai-before/report.json
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
These commands use each CLI's default model. For controlled comparisons, use
|
|
149
|
+
`--model` and `--judge-model` to select fixed writer and judge models available
|
|
150
|
+
in your environment. `--judge-agent` selects a separate evaluator CLI; otherwise
|
|
151
|
+
the writer's CLI is used. Same-model judging can favor the writer's style.
|
|
152
|
+
Claude trials use `--agent claude`. AI trials require MeCab; literal mode is
|
|
153
|
+
available only for deterministic detector evaluation.
|
|
154
|
+
|
|
155
|
+
Each trial performs these steps:
|
|
156
|
+
|
|
157
|
+
1. Create a fresh review session and generate its actual saved review prompt.
|
|
158
|
+
2. Supply the prompt and source checklists to the writer, requesting one JSON
|
|
159
|
+
paragraph per corpus ID. Faithful paragraphs can remain unchanged.
|
|
160
|
+
3. Install revisions in the temporary trial manuscript and run mechanical
|
|
161
|
+
verification for scope, inline preservation, and structure.
|
|
162
|
+
4. Invoke the judge separately with original and revised text labelled A/B,
|
|
163
|
+
alternating the order across trials. It receives source evidence but no
|
|
164
|
+
candidate findings or expected calibration answers.
|
|
165
|
+
5. Summarize readability, checklist retention, additions, substitutions,
|
|
166
|
+
calibration, and mechanical verification separately.
|
|
167
|
+
|
|
168
|
+
The writer receives evidence checklists, so the trial measures an
|
|
169
|
+
evidence-assisted review workflow. It does not simulate every manuscript review.
|
|
170
|
+
The judge sees original source evidence, so neutral labels reduce presentation
|
|
171
|
+
bias without guaranteeing full blindness.
|
|
172
|
+
|
|
173
|
+
## Read the AI results
|
|
174
|
+
|
|
175
|
+
| Metric | Interpretation |
|
|
176
|
+
| --- | --- |
|
|
177
|
+
| `sentence_clarity` | Actors, actions, conditions, and sentence relationships are understandable |
|
|
178
|
+
| `paragraph_coherence` | Sentences form a connected explanation |
|
|
179
|
+
| `fact_retention` | Percentage of supplied checklist entries retained, including explicit editorial constraints |
|
|
180
|
+
| `addition_free_paragraphs` | Percentage with no unsupported additions identified by the judge |
|
|
181
|
+
| `substitution_free_paragraphs` | Percentage with no substitutions identified by the judge |
|
|
182
|
+
| Calibration `accuracy` | Percentage of revision-pair dispositions matching the expected answers |
|
|
183
|
+
| Calibration `balanced_accuracy` | Mean recall across `accept`, `reject`, and `needs-evidence` classes |
|
|
184
|
+
| Mechanical verification pass rate | Percentage of trials passing the existing mechanical verifier |
|
|
185
|
+
|
|
186
|
+
Readability is rated per paragraph on an ordinal scale: 1 means hard to
|
|
187
|
+
understand, 2 means some ambiguity or distracting framing, and 3 means clear.
|
|
188
|
+
Ratings are mapped to 0, 50, and 100 and averaged. These averages are descriptive
|
|
189
|
+
summaries, not validated interval measurements. Inspect the paragraph reasons
|
|
190
|
+
and actual revisions alongside the numbers.
|
|
191
|
+
|
|
192
|
+
`ai.trials` contains each trial's `original`, `revision`, and `delta` metrics;
|
|
193
|
+
`delta` is revision minus original. `ai.summary` retains means, population
|
|
194
|
+
standard deviations, minima, and maxima. `ai_delta` compares these summary means
|
|
195
|
+
between runs. In particular, `ai_delta.delta.sentence_clarity` compares the
|
|
196
|
+
within-trial clarity improvement of the new run with that of the baseline.
|
|
197
|
+
|
|
198
|
+
For an illustrative example, clarity of 50 before rewriting and 75 afterwards
|
|
199
|
+
means a within-trial delta of +25. If the next run's delta is +30, the improvement
|
|
200
|
+
relative to the baseline is +5 points. These are example numbers, not measured
|
|
201
|
+
results. A readability gain with lower retention or new unsupported facts should
|
|
202
|
+
not be accepted merely because it scores higher.
|
|
203
|
+
|
|
204
|
+
One trial is a smoke test. Use at least three to inspect variation; the runner
|
|
205
|
+
provides no significance test. Poor calibration warrants inspection before
|
|
206
|
+
interpreting quality results. `meaning_verified` remains `false` regardless of
|
|
207
|
+
scores or mechanical pass rate.
|
|
208
|
+
|
|
209
|
+
## Comparison conditions and artifacts
|
|
210
|
+
|
|
211
|
+
Comparisons require the same corpus, document, benchmark identity, scoring
|
|
212
|
+
version, analyzer, and dictionary. Reports with configuration fingerprints also
|
|
213
|
+
check the fixed configuration. AI comparisons additionally require matching
|
|
214
|
+
judge rubric and calibration fingerprints, CLI versions, and actual reported
|
|
215
|
+
writer and judge models. Missing actual model identity prevents AI comparison.
|
|
216
|
+
|
|
217
|
+
Keep CLI user configuration consistent as well. Reports record criteria, rules,
|
|
218
|
+
source, harness, and analyzer fingerprints, but a fingerprint cannot restore old
|
|
219
|
+
content: retain the source revision and any uncommitted changes needed to
|
|
220
|
+
reproduce the run. A changed corpus, judge rubric, or calibration set needs a
|
|
221
|
+
new baseline. Compare the intended criteria or detector change only after the
|
|
222
|
+
other evaluation conditions are fixed.
|
|
223
|
+
|
|
224
|
+
AI trials require installed, authenticated local Codex or Claude CLIs. They may
|
|
225
|
+
call their configured remote model providers and consume account usage. The
|
|
226
|
+
runner uses argument arrays, read-only Codex execution or tool-disabled Claude
|
|
227
|
+
execution, and a per-invocation timeout (`--timeout`, default 300 seconds).
|
|
228
|
+
Missing CLIs, authentication failures, timeouts, and invalid responses fail
|
|
229
|
+
explicitly. See [the adapter](../lib/asciidoc_pubkit/local_evaluator.rb) for the
|
|
230
|
+
required flags; older CLIs may need an update.
|
|
231
|
+
|
|
232
|
+
Outputs are saved under the chosen directory, including `report.json`, AI-mode
|
|
233
|
+
`detection.json`, and per-trial review sessions, verification results, prompts,
|
|
234
|
+
and evaluator responses. Existing output directories are never replaced.
|
|
235
|
+
Partial artifacts remain after a failure. Keep results under ignored `.pubkit/`;
|
|
236
|
+
do not commit private evaluation artifacts.
|
|
237
|
+
|
|
238
|
+
For the version 1.0.1 yomiyasu v1.0.6 adaptation, the expanded v2 deterministic
|
|
239
|
+
benchmark ran before and after the criteria change: precision, recall, F1, and
|
|
240
|
+
location accuracy were all 100, with zero deltas. The suite passed 203 tests and
|
|
241
|
+
2,552 assertions with real MeCab/IPADIC. These are detector and workflow checks.
|
|
242
|
+
External AI rewrite-and-judge trials have not yet been run for this change, so
|
|
243
|
+
its readability and preservation improvement remains unmeasured.
|
|
244
|
+
|
|
245
|
+
[Development](development.md) · [Manuscript scoring](scoring.md) ·
|
|
246
|
+
[Back to README](../README.md)
|
data/docs/references.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# References
|
|
2
|
+
|
|
3
|
+
The shared criteria and default questions draw on the following editorial
|
|
4
|
+
sources. Their stylistic choices differ, including whether headings should state
|
|
5
|
+
conclusions. Candidate detection therefore leaves contextual judgment, document
|
|
6
|
+
structure, and final edits to the reviewer.
|
|
7
|
+
|
|
8
|
+
- [natural-japanese](https://github.com/coji/natural-japanese): separates mechanical
|
|
9
|
+
detection from contextual judgment and identifies repetitive framing. Applied
|
|
10
|
+
here: candidate findings feed a contextual review prompt, while phrases such as
|
|
11
|
+
`重要なのは` and `このように` invite inspection rather than automatic deletion.
|
|
12
|
+
- [yomiyasu](https://github.com/nanaism/yomiyasu):
|
|
13
|
+
informs evidence-based review of
|
|
14
|
+
metaphorical operations, distinctions between instructions and capabilities,
|
|
15
|
+
and separate assessment of meaning preservation and readability. Applied here:
|
|
16
|
+
four limited metaphor patterns and third-sentence repetition locations inform
|
|
17
|
+
candidate detection; the shared criteria require evidence for concrete rewrites.
|
|
18
|
+
The 1.0.1 update adapts the structural comparison and sentence-function
|
|
19
|
+
guidance from [v1.0.6, commit 4075fc3](https://github.com/nanaism/yomiyasu/commit/4075fc34fb0333ca1fe42d32cd619338f4a138ba):
|
|
20
|
+
compare modifier and quantity targets, condition scope, parallel relationships,
|
|
21
|
+
and order before and after revision; preserve sentence function separately
|
|
22
|
+
from plain or polite style. The new examples are original project fixtures.
|
|
23
|
+
Markdown-specific bold fixes and numeric style thresholds are not imported.
|
|
24
|
+
- [日本語技術文書の文章規範](https://gist.github.com/k16shikano/fd287c3133457c4fd8f5601d34aa817d):
|
|
25
|
+
informs paragraph logic, evidence scope, and meaningful uncertainty. Applied
|
|
26
|
+
here: the shared criteria start from each paragraph's technical purpose and
|
|
27
|
+
preserve necessary conditions, uncertainty, and exact terminology.
|
|
28
|
+
- [AI臭い文章とは何なのか](https://speakerdeck.com/nasuvitz/ai-kusai-bunshou-toha-nanina-no-ka):
|
|
29
|
+
provides examples of unnecessary contrast, abstract referents, and paired short
|
|
30
|
+
sentences. Applied here: the shared criteria ask reviewers to inspect these
|
|
31
|
+
patterns in context and recover concrete referents and connected explanations.
|
|
32
|
+
|
|
33
|
+
The development evaluation adapts ideas from the following primary research;
|
|
34
|
+
its engineering audience, corpus, and rubric do not reproduce those benchmarks.
|
|
35
|
+
Research texts and datasets are not redistributed here.
|
|
36
|
+
|
|
37
|
+
- [Evaluation of Document-Level Text Simplification in Japanese](https://aclanthology.org/2026.lrec-1.85/)
|
|
38
|
+
(Yamashita et al., LREC 2026): separates information preservation from sentence
|
|
39
|
+
and document simplicity and evaluates LLM judgments against human annotations.
|
|
40
|
+
Its elementary-school audience and Wikipedia corpus differ from this project.
|
|
41
|
+
Applied here: the scoring rubric separates sentence clarity from paragraph
|
|
42
|
+
coherence, and the development judge evaluates fact retention independently.
|
|
43
|
+
- [Evaluating Factuality in Text Simplification](https://aclanthology.org/2022.acl-long.506/)
|
|
44
|
+
(Devaraj et al., ACL 2022): distinguishes insertion, deletion, and substitution
|
|
45
|
+
errors. Applied here: development trials check each source fact and report
|
|
46
|
+
unsupported additions and substitutions separately; a readable rewrite can
|
|
47
|
+
still fail preservation review.
|
|
48
|
+
- [Evaluating Document Simplification: On the Importance of Separately Assessing Simplicity and Meaning Preservation](https://aclanthology.org/2024.readi-1.1/)
|
|
49
|
+
(Cripwell et al., READI 2024): motivates separate readability and preservation
|
|
50
|
+
scores. Applied here: readability dimensions and preservation outcomes remain
|
|
51
|
+
separate in benchmark reports; the direct manuscript score makes no
|
|
52
|
+
preservation claim. SARI-style overlap metrics are not adopted.
|
|
53
|
+
|
|
54
|
+
[Back to README](../README.md)
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Prose replacements
|
|
2
|
+
|
|
3
|
+
The replacement commands apply author-supplied mechanical replacement rules without MeCab or an AI
|
|
4
|
+
CLI. Review candidates and glossary variants remain advisory and are never
|
|
5
|
+
implicitly applied. Replacement rules are separate from review rules.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
asciidoc-pubkit replace check book.adoc --rules replacements.yml
|
|
9
|
+
asciidoc-pubkit replace diff book.adoc --rules replacements.yml
|
|
10
|
+
asciidoc-pubkit replace apply book.adoc --rules replacements.yml
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`check` reports original text, proposed text, rule IDs (`rule-1`, etc.), source
|
|
14
|
+
paths, one-based Unicode lines/columns, and a coverage-notice count. Its exit code
|
|
15
|
+
is 1 when replacements are available, 0 otherwise. `diff` previews unified diffs
|
|
16
|
+
without editing; it requires the external `diff` command. `apply` explicitly
|
|
17
|
+
authorizes source replacement without prompting. Successful diff/apply commands
|
|
18
|
+
return 0; invalid rules, conflicts, unsafe edits, and input/output failures return
|
|
19
|
+
2. Check/diff accept `--output` for a new file only; apply rejects `--output`.
|
|
20
|
+
|
|
21
|
+
Starting with version 0.8.2, invalid rule files report their original YAML file
|
|
22
|
+
and one-based line number on the first error line, followed by the existing
|
|
23
|
+
reason on the next line. Imported files and entries in pattern arrays retain
|
|
24
|
+
their own source locations. For example:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
Error: /path/to/prh.yml:162
|
|
28
|
+
Unsupported regex flags; only optional i is supported (all matches are collected).
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Rules are validated before any manuscript is replaced. All replacement commands
|
|
32
|
+
stop with exit code 2 on invalid rules, including errors found in imported files.
|
|
33
|
+
|
|
34
|
+
All three accept `--lang ja`, `--base-dir`, `--config`, and `--only` (an included
|
|
35
|
+
source file). Normal configuration discovery and `review.base_dir`, `language`,
|
|
36
|
+
`attributes`, and `exclude` control parsing and selection. `--rules` is required;
|
|
37
|
+
`review.rules` and glossary entries do not supply replacement rules. There are
|
|
38
|
+
no built-in replacement rules and no automatic search for `prh.yml`.
|
|
39
|
+
|
|
40
|
+
### Limited prh-format rules
|
|
41
|
+
|
|
42
|
+
The supported format is a strict subset of [prh](https://github.com/prh/prh):
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
version: 1
|
|
46
|
+
rules:
|
|
47
|
+
- expected: '®'
|
|
48
|
+
pattern: '®'
|
|
49
|
+
- expected: '($1)'
|
|
50
|
+
pattern: '/(([^()\r\n]+))/'
|
|
51
|
+
specs:
|
|
52
|
+
- from: '設定(任意)'
|
|
53
|
+
to: '設定(任意)'
|
|
54
|
+
- expected: '/'
|
|
55
|
+
patterns:
|
|
56
|
+
- '/'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The root requires `version: 1` and accepts optional `rules` and `imports` arrays.
|
|
60
|
+
Starting with version 0.8.1, omitted arrays default to empty. Version 0.8.0
|
|
61
|
+
requires `rules` and rejects `imports`. Each rule requires a string
|
|
62
|
+
`expected` (empty strings permit deletion) and exactly one of `pattern` (a
|
|
63
|
+
nonempty string or, starting with version 0.8.1, a nonempty array of nonempty
|
|
64
|
+
strings) or `patterns` (a nonempty array of nonempty strings). Array-valued
|
|
65
|
+
`pattern` is equivalent to `patterns`; specifying both keys is rejected. Optional
|
|
66
|
+
`specs` is an array of exact `from`/`to` string pairs, validated on load. Specs
|
|
67
|
+
exercise the rule on plain text, not AsciiDoc selection or inline protection.
|
|
68
|
+
|
|
69
|
+
Strings not beginning with `/` match literally. `/.../` denotes a regex; the
|
|
70
|
+
version 0.8.1 also accepts `/.../i` for Ruby case-insensitive matching.
|
|
71
|
+
Version 0.8.0 rejects all flags. All occurrences are collected. The implementation
|
|
72
|
+
uses Ruby regexes with
|
|
73
|
+
a timeout and accepts a limited common syntax: character classes, ordinary
|
|
74
|
+
captures, noncapturing groups, lookarounds, alternatives, anchors, quantifiers,
|
|
75
|
+
and the escapes `\n`, `\r`, `\t`, `\d`, `\D`, `\s`, `\S`, `\w`, `\W`
|
|
76
|
+
and escaped punctuation. Ruby regex character-class behavior applies; this is
|
|
77
|
+
not a JavaScript regex engine or a promise of full prh equivalence. Engine-specific
|
|
78
|
+
groups/escapes and flags other than a single `i` are rejected. A leading literal slash must be expressed
|
|
79
|
+
as an escaped regex, for example `/\//`. Zero-length matches are rejected.
|
|
80
|
+
|
|
81
|
+
Replacement strings support `$1` through `$99` for existing capture groups and
|
|
82
|
+
`$$` for a literal dollar sign. Unsupported dollar references are rejected when
|
|
83
|
+
matched. Missing optional captures expand to empty strings. YAML single quotes
|
|
84
|
+
are recommended to keep backslashes literal. Unknown fields, including
|
|
85
|
+
`options` and `regexpMustEmpty`, and omitted patterns are rejected rather than
|
|
86
|
+
ignored. prh's automatic pattern generation is not supported.
|
|
87
|
+
|
|
88
|
+
For example, version 0.8.1 also accepts:
|
|
89
|
+
|
|
90
|
+
```yaml
|
|
91
|
+
version: 1
|
|
92
|
+
rules:
|
|
93
|
+
- expected: 'ハードウェア'
|
|
94
|
+
pattern:
|
|
95
|
+
- 'ハードウエア'
|
|
96
|
+
- 'ハードウェアー'
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Each array entry uses the same literal/regex syntax and validation as a single
|
|
100
|
+
pattern. Arrays do not change supported flags or overlap handling.
|
|
101
|
+
|
|
102
|
+
### Limited ECMAScript boundary compatibility
|
|
103
|
+
|
|
104
|
+
Version 0.8.1 translates `\b` and `\B` outside character classes into Ruby
|
|
105
|
+
lookarounds with ECMAScript word-character semantics, following prh's default
|
|
106
|
+
Unicode mode. Word characters are ASCII letters, digits, and underscore; Japanese
|
|
107
|
+
characters are non-word characters. Thus `/\bTips\b/` matches `Tips` in
|
|
108
|
+
`前Tips後`, but not in `Tips2`, `_Tips`, or `ATips`.
|
|
109
|
+
With `/i`, long s (`ſ`) and Kelvin sign (`K`) also count as word characters under
|
|
110
|
+
ECMAScript Unicode case folding. The generated assertions add no capture groups
|
|
111
|
+
and preserve original match offsets. Inside a character class, `\b` means a
|
|
112
|
+
backspace character; `\B` there is rejected. Escaped literal backslashes are
|
|
113
|
+
preserved.
|
|
114
|
+
|
|
115
|
+
Only the boundary assertions emulate ECMAScript. `/i` uses Ruby's
|
|
116
|
+
`Regexp::IGNORECASE`; Unicode case folding can differ from JavaScript (for
|
|
117
|
+
example multi-character folds). Other constructs, including whitespace classes,
|
|
118
|
+
retain Ruby semantics. This is limited prh compatibility, not full ECMAScript
|
|
119
|
+
conformance. Flags `g`, `m`, `s`, `u`, `y`, `d`, and `v` and duplicate `i` are
|
|
120
|
+
rejected; all occurrences are already collected independently of `g`.
|
|
121
|
+
|
|
122
|
+
### Importing replacement rules
|
|
123
|
+
|
|
124
|
+
Version 0.8.1 supports nested `imports`; version 0.8.0 does not. For example:
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
version: 1
|
|
128
|
+
imports:
|
|
129
|
+
- ../../rules/prh.yml
|
|
130
|
+
- path: ./terminology.yml
|
|
131
|
+
rules:
|
|
132
|
+
- expected: '®'
|
|
133
|
+
pattern: '®'
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Each entry is a nonempty local file path string or a mapping containing exactly
|
|
137
|
+
`path`. Relative paths resolve from the importing YAML file, including nested
|
|
138
|
+
imports, independently of the working directory and manuscript base directory.
|
|
139
|
+
Absolute local paths are also accepted; URL imports are rejected. An import-only
|
|
140
|
+
file may omit `rules`. A file containing only `version: 1` is also valid and
|
|
141
|
+
contributes no rules. With no imported or local rules, `check`, `diff`, and
|
|
142
|
+
`apply` succeed without changing manuscript sources, and `diff` emits no patch.
|
|
143
|
+
Starting with version 0.8.1, a bare `rules:`, `rules: null`, and `rules: ~`
|
|
144
|
+
also contribute no local rules, just like omission or `rules: []`; imported rules
|
|
145
|
+
are still loaded. Other non-array values remain invalid. This normalization
|
|
146
|
+
applies only to `rules`, not to `imports` or individual rule fields.
|
|
147
|
+
Every imported file must use version 1 and pass the same
|
|
148
|
+
strict rule validation and specs as the entry file.
|
|
149
|
+
|
|
150
|
+
Imports are loaded in listed order, recursively before each file's own rules.
|
|
151
|
+
Each physical file is loaded once per plan, including repeated paths, symlink
|
|
152
|
+
aliases, and shared dependencies. Rule IDs are assigned across the flattened
|
|
153
|
+
set. Cycles (including symlink aliases), missing files, and import chains deeper
|
|
154
|
+
than 100 files fail rather than silently omitting rules. Imported and local rules
|
|
155
|
+
are combined, not overridden: overlapping replacement candidates remain errors
|
|
156
|
+
and replacements are still calculated only against the original text.
|
|
157
|
+
|
|
158
|
+
Import options such as `ignoreRules` and `disableImports` remain unsupported and
|
|
159
|
+
are rejected. Source selection and protection are unchanged by imports.
|
|
160
|
+
|
|
161
|
+
### Selection and preservation
|
|
162
|
+
|
|
163
|
+
Only unambiguously source-mapped running prose in the existing default review
|
|
164
|
+
scope is eligible. Headings, lists, tables, quotations, listing/source, literal,
|
|
165
|
+
and passthrough blocks are excluded. Recognized inline code, quotations, URLs,
|
|
166
|
+
macros, and attribute references are protected by the existing conservative
|
|
167
|
+
inline heuristic, not a complete inline parser. A match overlapping any protected
|
|
168
|
+
span is skipped; matching is performed on the original text, never on blanked
|
|
169
|
+
placeholders. Backtick-to-bold and list-marker conversions are outside this scope.
|
|
170
|
+
|
|
171
|
+
Candidates are calculated once against the original sources; replacement results
|
|
172
|
+
are not searched again. Overlapping edits are conflicts, not resolved by rule
|
|
173
|
+
order. Matches/results containing line breaks are rejected. Source files retain
|
|
174
|
+
UTF-8 bytes, original line endings, and unrelated content; repeated include
|
|
175
|
+
occurrences must not create overlapping edits.
|
|
176
|
+
|
|
177
|
+
Before presenting a plan, the complete captured source set is copied to temporary
|
|
178
|
+
staging and reparsed. Parsing diagnostics, structural changes, new/deleted protected
|
|
179
|
+
inline tokens, and protected-content/source-membership changes reject the plan.
|
|
180
|
+
Relative includes within the base directory are supported. Absolute includes and
|
|
181
|
+
includes whose paths depend on the original filesystem may fail staged validation;
|
|
182
|
+
they are not rewritten or silently accepted. Symlink entrypoints are rejected.
|
|
183
|
+
|
|
184
|
+
Apply stages all changed files beside their destinations, checks all captured
|
|
185
|
+
source bytes against the plan, and renames the prepared files into place while
|
|
186
|
+
preserving permission bits. An ordinary installation error restores sources
|
|
187
|
+
already installed. This is not a crash-atomic transaction across multiple files;
|
|
188
|
+
keep manuscripts under version control and avoid concurrent edits during apply.
|
|
189
|
+
No review session is created or replaced. Existing sessions retain their original
|
|
190
|
+
baselines; applying replacements can make a session stale for prompt generation.
|
|
191
|
+
Mechanical validation does not establish semantic correctness.
|
|
192
|
+
|
|
193
|
+
[Back to README](../README.md)
|