eyeprolog 1.5.15 → 1.5.17
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.
- package/examples/book/README.md +9 -9
- package/examples/book/chapter-39/{02-answer.pl → 01-answer.pl} +1 -1
- package/examples/book/chapter-39/{01-program.pl → 07-program.pl} +1 -1
- package/package.json +1 -1
- package/test/run-regression.mjs +45 -20
- package/the-art-of-eyeprolog.md +2729 -2126
- package/tools/generate-predicate-reference.mjs +20 -8
- /package/examples/book/chapter-39/{03-answer-2.pl → 02-answer-2.pl} +0 -0
- /package/examples/book/chapter-39/{04-answer-3.pl → 03-answer-3.pl} +0 -0
- /package/examples/book/chapter-39/{05-cost.pl → 04-cost.pl} +0 -0
- /package/examples/book/chapter-39/{06-message.pl → 05-message.pl} +0 -0
- /package/examples/book/chapter-39/{07-task.pl → 06-task.pl} +0 -0
package/examples/book/README.md
CHANGED
|
@@ -236,15 +236,15 @@ npm run generate
|
|
|
236
236
|
- [01-city.pl](chapter-38/01-city.pl)
|
|
237
237
|
- [02-look_ahead.pl](chapter-38/02-look_ahead.pl) — Part 3-oriented definite clause grammars
|
|
238
238
|
|
|
239
|
-
## Chapter 39:
|
|
240
|
-
|
|
241
|
-
- [01-
|
|
242
|
-
- [02-answer.pl](chapter-39/02-answer.pl)
|
|
243
|
-
- [03-answer-
|
|
244
|
-
- [04-
|
|
245
|
-
- [05-
|
|
246
|
-
- [06-
|
|
247
|
-
- [07-
|
|
239
|
+
## Chapter 39: Predicate reference
|
|
240
|
+
|
|
241
|
+
- [01-answer.pl](chapter-39/01-answer.pl) — Library relations by programming role
|
|
242
|
+
- [02-answer-2.pl](chapter-39/02-answer-2.pl)
|
|
243
|
+
- [03-answer-3.pl](chapter-39/03-answer-3.pl)
|
|
244
|
+
- [04-cost.pl](chapter-39/04-cost.pl)
|
|
245
|
+
- [05-message.pl](chapter-39/05-message.pl)
|
|
246
|
+
- [06-task.pl](chapter-39/06-task.pl)
|
|
247
|
+
- [07-program.pl](chapter-39/07-program.pl) — Specialized library implementation notes
|
|
248
248
|
|
|
249
249
|
## Chapter 40: Running EyeProlog: command line and corpus
|
|
250
250
|
|
package/package.json
CHANGED
package/test/run-regression.mjs
CHANGED
|
@@ -4799,7 +4799,30 @@ function documentationSyncCases() {
|
|
|
4799
4799
|
const section = between(book, '<!-- eyeprolog-predicate-reference:start -->', '<!-- eyeprolog-predicate-reference:end -->');
|
|
4800
4800
|
assertEqual(section.split('\n').some((line) => line.trimStart().startsWith('|')), false, 'predicate reference avoids Markdown tables and horizontal overflow');
|
|
4801
4801
|
assertEqual((section.match(/^- \*\*`/gm) ?? []).length, 518, 'one stacked reference entry per predicate');
|
|
4802
|
+
assertEqual((section.match(/<a id="predicate-reference-\d{4}"><\/a>/g) ?? []).length, 518, 'one explicit stable anchor per predicate');
|
|
4803
|
+
assertEqual((section.match(/\]\(#predicate-reference-\d{4}\)/g) ?? []).length, 518, 'one direct index link per predicate');
|
|
4804
|
+
assertNotIncludes(section, '[Symbols](#predicate-reference-symbols)', 'predicate index does not rely on renderer-generated group anchors');
|
|
4805
|
+
assertIncludes(section, 'stable numeric IDs instead of relying on Markdown heading-slug rules', 'renderer-independent predicate anchors');
|
|
4802
4806
|
assertIncludes(section, 'wrap naturally on narrow screens without horizontal scrolling', 'responsive predicate reference layout');
|
|
4807
|
+
|
|
4808
|
+
const chapter = between(book, '## 39. Predicate reference', '## 40. Running EyeProlog: command line and corpus');
|
|
4809
|
+
assertEqual(chapter.split('\n').some((line) => line.trimStart().startsWith('|')), false, 'Chapter 39 uses one wrapping stacked layout without Markdown tables');
|
|
4810
|
+
const orderedHeadings = [
|
|
4811
|
+
'### How to read this chapter',
|
|
4812
|
+
'### Core registry',
|
|
4813
|
+
'### Normal-mode extensions',
|
|
4814
|
+
'### Bundled libraries',
|
|
4815
|
+
'### Library relations by programming role',
|
|
4816
|
+
'### Interoperability, autoloading, and portability',
|
|
4817
|
+
'### Specialized library implementation notes',
|
|
4818
|
+
'### Complete predicate indicator reference',
|
|
4819
|
+
];
|
|
4820
|
+
let previous = -1;
|
|
4821
|
+
for (const heading of orderedHeadings) {
|
|
4822
|
+
const position = chapter.indexOf(heading);
|
|
4823
|
+
assertEqual(position > previous, true, `Chapter 39 section order: ${heading}`);
|
|
4824
|
+
previous = position;
|
|
4825
|
+
}
|
|
4803
4826
|
},
|
|
4804
4827
|
},
|
|
4805
4828
|
{
|
|
@@ -7560,7 +7583,7 @@ function bookReferenceDocumentationIssues() {
|
|
|
7560
7583
|
if (book.includes('EyeProlog does not perform it.')) {
|
|
7561
7584
|
issues.push('book contradicts implementation occurs-check behavior');
|
|
7562
7585
|
}
|
|
7563
|
-
for (const heading of ['## 38. Language and ISO profile', '## 39.
|
|
7586
|
+
for (const heading of ['## 38. Language and ISO profile', '## 39. Predicate reference', '## 40. Running EyeProlog: command line and corpus']) {
|
|
7564
7587
|
if (!book.includes(heading)) issues.push(`book is missing ${heading}`);
|
|
7565
7588
|
}
|
|
7566
7589
|
if (!guide.includes('[*The Art of EyeProlog*](../../the-art-of-eyeprolog.md) is the reference')) {
|
|
@@ -7807,26 +7830,31 @@ function registeredBuiltinSummary() {
|
|
|
7807
7830
|
|
|
7808
7831
|
function bookBuiltinNames() {
|
|
7809
7832
|
const book = fs.readFileSync(path.join(packageRoot, 'the-art-of-eyeprolog.md'), 'utf8');
|
|
7810
|
-
return documentedBuiltinNames(
|
|
7833
|
+
return documentedBuiltinNames(
|
|
7834
|
+
between(book, '<!-- eyeprolog-core-catalog:start -->', '<!-- eyeprolog-core-catalog:end -->'),
|
|
7835
|
+
);
|
|
7811
7836
|
}
|
|
7812
7837
|
|
|
7813
7838
|
function bookEyePrologLibraryNames() {
|
|
7814
7839
|
const book = fs.readFileSync(path.join(packageRoot, 'the-art-of-eyeprolog.md'), 'utf8');
|
|
7815
7840
|
const iso = new Set(registeredBuiltinNames());
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
7841
|
+
const section = between(book, '<!-- eyeprolog-library-catalog:start -->', '<!-- eyeprolog-library-catalog:end -->');
|
|
7842
|
+
const exports = section.split('\n')
|
|
7843
|
+
.filter((line) => line.trimStart().startsWith('**Exports:**'))
|
|
7844
|
+
.join('\n');
|
|
7845
|
+
return documentedBuiltinNames(exports).filter((indicator) => !iso.has(indicator));
|
|
7820
7846
|
}
|
|
7821
7847
|
|
|
7822
7848
|
function bookLibraryModuleIssues() {
|
|
7823
7849
|
const book = fs.readFileSync(path.join(packageRoot, 'the-art-of-eyeprolog.md'), 'utf8');
|
|
7824
7850
|
const section = between(book, '<!-- eyeprolog-library-catalog:start -->', '<!-- eyeprolog-library-catalog:end -->');
|
|
7825
7851
|
const documented = new Map();
|
|
7826
|
-
|
|
7827
|
-
|
|
7852
|
+
const lines = section.split('\n');
|
|
7853
|
+
for (let i = 0; i < lines.length; i++) {
|
|
7854
|
+
const match = lines[i].match(/^- \*\*`library\(([^)`]+)\)`\*\*/);
|
|
7828
7855
|
if (match == null) continue;
|
|
7829
|
-
|
|
7856
|
+
const exports = lines[i + 1] ?? '';
|
|
7857
|
+
documented.set(match[1], documentedBuiltinNames(exports));
|
|
7830
7858
|
}
|
|
7831
7859
|
|
|
7832
7860
|
const issues = [];
|
|
@@ -7860,18 +7888,12 @@ function bookBuiltinSummary() {
|
|
|
7860
7888
|
return { entries: Number(match[1]), names: Number(match[2]) };
|
|
7861
7889
|
}
|
|
7862
7890
|
|
|
7863
|
-
function documentedBuiltinNames(section
|
|
7891
|
+
function documentedBuiltinNames(section) {
|
|
7864
7892
|
const names = [];
|
|
7865
|
-
for (const
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
const arity = match[2].trim() === '' ? 0 : match[2].split(',').length;
|
|
7870
|
-
names.push(`${match[1]}/${arity}`);
|
|
7871
|
-
}
|
|
7872
|
-
for (const match of catalogCell.matchAll(/`([^`\s]+)\/(\d+)`/g)) {
|
|
7873
|
-
names.push(`${match[1]}/${match[2]}`);
|
|
7874
|
-
}
|
|
7893
|
+
for (const match of section.matchAll(/`([^`]+)`/g)) {
|
|
7894
|
+
const indicator = match[1].match(/^(.+)\/(\d+)$/);
|
|
7895
|
+
if (indicator == null) continue;
|
|
7896
|
+
names.push(`${indicator[1]}/${indicator[2]}`);
|
|
7875
7897
|
}
|
|
7876
7898
|
return [...new Set(names)].sort();
|
|
7877
7899
|
}
|
|
@@ -8077,6 +8099,9 @@ function markdownAnchors(file) {
|
|
|
8077
8099
|
counts.set(base, count + 1);
|
|
8078
8100
|
anchors.add(count === 0 ? base : `${base}-${count}`);
|
|
8079
8101
|
}
|
|
8102
|
+
for (const match of text.matchAll(/<(?:a|[A-Za-z][A-Za-z0-9:-]*)\b[^>]*\b(?:id|name)=["']([^"']+)["'][^>]*>/g)) {
|
|
8103
|
+
anchors.add(match[1]);
|
|
8104
|
+
}
|
|
8080
8105
|
return anchors;
|
|
8081
8106
|
}
|
|
8082
8107
|
|