@markup-carve/carve-lsp 0.1.2 → 0.1.4
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/README.md +61 -14
- package/dist/analyze.d.ts +15 -1
- package/dist/analyze.js +214 -16
- package/dist/analyze.js.map +1 -1
- package/dist/analyze.test.js +29 -1
- package/dist/analyze.test.js.map +1 -1
- package/dist/captions.d.ts +49 -0
- package/dist/captions.js +124 -0
- package/dist/captions.js.map +1 -0
- package/dist/codelens.js +12 -0
- package/dist/codelens.js.map +1 -1
- package/dist/codelens.test.js +5 -0
- package/dist/codelens.test.js.map +1 -1
- package/dist/colon-fence-kinds.test.d.ts +1 -0
- package/dist/colon-fence-kinds.test.js +128 -0
- package/dist/colon-fence-kinds.test.js.map +1 -0
- package/dist/colon-fences.d.ts +24 -0
- package/dist/colon-fences.js +174 -0
- package/dist/colon-fences.js.map +1 -0
- package/dist/colon-fences.test.d.ts +1 -0
- package/dist/colon-fences.test.js +23 -0
- package/dist/colon-fences.test.js.map +1 -0
- package/dist/completion.d.ts +6 -2
- package/dist/completion.js +84 -8
- package/dist/completion.js.map +1 -1
- package/dist/completion.test.js +7 -0
- package/dist/completion.test.js.map +1 -1
- package/dist/composite-figure-crossref.test.d.ts +1 -0
- package/dist/composite-figure-crossref.test.js +265 -0
- package/dist/composite-figure-crossref.test.js.map +1 -0
- package/dist/composite-figure.test.d.ts +1 -0
- package/dist/composite-figure.test.js +76 -0
- package/dist/composite-figure.test.js.map +1 -0
- package/dist/definition.d.ts +4 -2
- package/dist/definition.js +28 -5
- package/dist/definition.js.map +1 -1
- package/dist/dependencies.d.ts +15 -0
- package/dist/dependencies.js +59 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/diagnostic-scheduler.d.ts +58 -0
- package/dist/diagnostic-scheduler.js +70 -0
- package/dist/diagnostic-scheduler.js.map +1 -0
- package/dist/diagnostic-scheduler.test.d.ts +1 -0
- package/dist/diagnostic-scheduler.test.js +75 -0
- package/dist/diagnostic-scheduler.test.js.map +1 -0
- package/dist/document-highlights.d.ts +2 -0
- package/dist/document-highlights.js +21 -0
- package/dist/document-highlights.js.map +1 -0
- package/dist/document-highlights.test.d.ts +1 -0
- package/dist/document-highlights.test.js +13 -0
- package/dist/document-highlights.test.js.map +1 -0
- package/dist/document-links.d.ts +3 -0
- package/dist/document-links.js +36 -0
- package/dist/document-links.js.map +1 -0
- package/dist/document-links.test.d.ts +1 -0
- package/dist/document-links.test.js +12 -0
- package/dist/document-links.test.js.map +1 -0
- package/dist/folding.d.ts +1 -0
- package/dist/folding.js +36 -1
- package/dist/folding.js.map +1 -1
- package/dist/folding.test.js +6 -1
- package/dist/folding.test.js.map +1 -1
- package/dist/format-corpus.test.d.ts +1 -0
- package/dist/format-corpus.test.js +16 -0
- package/dist/format-corpus.test.js.map +1 -0
- package/dist/format.d.ts +3 -0
- package/dist/format.js +38 -74
- package/dist/format.js.map +1 -1
- package/dist/format.test.js +27 -32
- package/dist/format.test.js.map +1 -1
- package/dist/hover.js +78 -19
- package/dist/hover.js.map +1 -1
- package/dist/include-cache.d.ts +26 -0
- package/dist/include-cache.js +74 -0
- package/dist/include-cache.js.map +1 -0
- package/dist/include-completion.d.ts +3 -0
- package/dist/include-completion.js +68 -0
- package/dist/include-completion.js.map +1 -0
- package/dist/include-completion.test.d.ts +1 -0
- package/dist/include-completion.test.js +15 -0
- package/dist/include-completion.test.js.map +1 -0
- package/dist/include-definition-denial.test.d.ts +1 -0
- package/dist/include-definition-denial.test.js +86 -0
- package/dist/include-definition-denial.test.js.map +1 -0
- package/dist/include-definition.d.ts +3 -0
- package/dist/include-definition.js +37 -0
- package/dist/include-definition.js.map +1 -0
- package/dist/include-features.test.d.ts +1 -0
- package/dist/include-features.test.js +133 -0
- package/dist/include-features.test.js.map +1 -0
- package/dist/include-path.d.ts +6 -0
- package/dist/include-path.js +31 -2
- package/dist/include-path.js.map +1 -1
- package/dist/include-settings.d.ts +2 -0
- package/dist/include-settings.js +1 -0
- package/dist/include-settings.js.map +1 -1
- package/dist/includes.d.ts +8 -0
- package/dist/includes.js +28 -7
- package/dist/includes.js.map +1 -1
- package/dist/inlay-hints.d.ts +3 -0
- package/dist/inlay-hints.js +43 -0
- package/dist/inlay-hints.js.map +1 -0
- package/dist/inlay-hints.test.d.ts +1 -0
- package/dist/inlay-hints.test.js +10 -0
- package/dist/inlay-hints.test.js.map +1 -0
- package/dist/lint-actions.d.ts +3 -0
- package/dist/lint-actions.js +90 -0
- package/dist/lint-actions.js.map +1 -0
- package/dist/lint-actions.test.d.ts +1 -0
- package/dist/lint-actions.test.js +31 -0
- package/dist/lint-actions.test.js.map +1 -0
- package/dist/no-git-dependencies.test.d.ts +1 -0
- package/dist/no-git-dependencies.test.js +243 -0
- package/dist/no-git-dependencies.test.js.map +1 -0
- package/dist/packaging.test.d.ts +1 -0
- package/dist/packaging.test.js +69 -0
- package/dist/packaging.test.js.map +1 -0
- package/dist/references.d.ts +2 -0
- package/dist/references.js +113 -21
- package/dist/references.js.map +1 -1
- package/dist/selection.d.ts +2 -0
- package/dist/selection.js +36 -0
- package/dist/selection.js.map +1 -0
- package/dist/selection.test.d.ts +1 -0
- package/dist/selection.test.js +10 -0
- package/dist/selection.test.js.map +1 -0
- package/dist/semantic.d.ts +5 -3
- package/dist/semantic.js +45 -4
- package/dist/semantic.js.map +1 -1
- package/dist/semantic.test.js +11 -0
- package/dist/semantic.test.js.map +1 -1
- package/dist/server-capabilities.test.d.ts +1 -0
- package/dist/server-capabilities.test.js +84 -0
- package/dist/server-capabilities.test.js.map +1 -0
- package/dist/server.js +353 -24
- package/dist/server.js.map +1 -1
- package/dist/settings.d.ts +11 -0
- package/dist/settings.js +50 -0
- package/dist/settings.js.map +1 -0
- package/dist/settings.test.d.ts +1 -0
- package/dist/settings.test.js +22 -0
- package/dist/settings.test.js.map +1 -0
- package/dist/spec-0-1-4-constructs.test.d.ts +1 -0
- package/dist/spec-0-1-4-constructs.test.js +101 -0
- package/dist/spec-0-1-4-constructs.test.js.map +1 -0
- package/dist/table-diagnostics.d.ts +3 -0
- package/dist/table-diagnostics.js +60 -0
- package/dist/table-diagnostics.js.map +1 -0
- package/dist/table-diagnostics.test.d.ts +1 -0
- package/dist/table-diagnostics.test.js +12 -0
- package/dist/table-diagnostics.test.js.map +1 -0
- package/dist/versioned-cache.d.ts +8 -0
- package/dist/versioned-cache.js +17 -0
- package/dist/versioned-cache.js.map +1 -0
- package/dist/versioned-cache.test.d.ts +1 -0
- package/dist/versioned-cache.test.js +13 -0
- package/dist/versioned-cache.test.js.map +1 -0
- package/dist/workspace-graph.d.ts +25 -0
- package/dist/workspace-graph.js +94 -0
- package/dist/workspace-graph.js.map +1 -0
- package/dist/workspace-graph.test.d.ts +1 -0
- package/dist/workspace-graph.test.js +31 -0
- package/dist/workspace-graph.test.js.map +1 -0
- package/dist/workspace-index.d.ts +40 -0
- package/dist/workspace-index.js +254 -0
- package/dist/workspace-index.js.map +1 -0
- package/dist/workspace-index.test.d.ts +1 -0
- package/dist/workspace-index.test.js +65 -0
- package/dist/workspace-index.test.js.map +1 -0
- package/dist/workspace-loader.d.ts +11 -0
- package/dist/workspace-loader.js +50 -0
- package/dist/workspace-loader.js.map +1 -0
- package/dist/workspace-loader.test.d.ts +1 -0
- package/dist/workspace-loader.test.js +19 -0
- package/dist/workspace-loader.test.js.map +1 -0
- package/package.json +4 -3
package/dist/completion.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { type CompletionItem, type Position } from 'vscode-languageserver/node.js';
|
|
2
|
+
import type { IndexedToken } from './workspace-index.js';
|
|
2
3
|
/**
|
|
3
4
|
* Context-aware completions driven by the text immediately before the cursor:
|
|
4
|
-
* - `::: ` opens
|
|
5
|
+
* - `::: ` opens a container -> canonical admonition kinds, and `figure`
|
|
5
6
|
* - `</#` cross-reference -> heading ids in the document
|
|
6
7
|
* - `[^` footnote reference -> defined footnote labels
|
|
7
8
|
* - `][` reference link -> defined link reference labels
|
|
8
9
|
*/
|
|
9
|
-
export
|
|
10
|
+
export interface CompletionContext {
|
|
11
|
+
workspaceTokens?: IndexedToken[];
|
|
12
|
+
}
|
|
13
|
+
export declare function completionAt(source: string, position: Position, context?: CompletionContext): CompletionItem[];
|
package/dist/completion.js
CHANGED
|
@@ -1,23 +1,38 @@
|
|
|
1
1
|
import { CompletionItemKind, } from 'vscode-languageserver/node.js';
|
|
2
2
|
import { parse, resolve } from '@markup-carve/carve';
|
|
3
|
+
import { captionTargets } from './captions.js';
|
|
3
4
|
/** The eight canonical admonition kinds (grammar PART 9 §12, Tier 1). */
|
|
4
5
|
const ADMONITIONS = ['note', 'tip', 'warning', 'danger', 'info', 'success', 'example', 'quote'];
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* `figure` is not one of them. It is RESERVED among the `:::` types (PART 9
|
|
8
|
+
* §4c): a BARE `::: figure` opener is one figure of ordered panels, and the same
|
|
9
|
+
* word with a title or a `[label]` is an ordinary container. Offering it beside
|
|
10
|
+
* the eight would say it is a ninth admonition, so it is offered separately and
|
|
11
|
+
* labelled for what it opens.
|
|
11
12
|
*/
|
|
12
|
-
|
|
13
|
+
const FIGURE_GROUP = 'figure';
|
|
14
|
+
export function completionAt(source, position, context = {}) {
|
|
13
15
|
const line = source.split(/\r?\n/)[position.line] ?? '';
|
|
14
16
|
const prefix = line.slice(0, position.character);
|
|
15
17
|
let match;
|
|
16
18
|
if ((match = /:::\s*([\w-]*)$/.exec(prefix))) {
|
|
17
|
-
return
|
|
19
|
+
return [
|
|
20
|
+
...ADMONITIONS.map((kind) => completion(kind, CompletionItemKind.Keyword, match[1], position, 'Admonition kind')),
|
|
21
|
+
completion(FIGURE_GROUP, CompletionItemKind.Struct, match[1], position, 'Composite figure'),
|
|
22
|
+
];
|
|
18
23
|
}
|
|
19
24
|
if ((match = /<\/#([\w-]*)$/.exec(prefix))) {
|
|
20
|
-
|
|
25
|
+
// A crossref reaches a captioned host as well as a heading (PART 9R R4).
|
|
26
|
+
// Offering only heading ids said the others were not targets, which is the
|
|
27
|
+
// reading that made a `</#fig>` naming a figure look like a typo.
|
|
28
|
+
const workspace = (context.workspaceTokens ?? [])
|
|
29
|
+
.filter((token) => token.declaration && (token.kind === 'heading' || token.kind === 'caption'))
|
|
30
|
+
.map((token) => completion(token.key, CompletionItemKind.Reference, match[1], position, `${token.kind} in workspace`));
|
|
31
|
+
return uniqueCompletions([
|
|
32
|
+
...headingIds(source).map((id) => completion(id, CompletionItemKind.Reference, match[1], position, 'Heading id')),
|
|
33
|
+
...resolvableCaptionIds(source).map(({ id, detail }) => completion(id, CompletionItemKind.Reference, match[1], position, detail)),
|
|
34
|
+
...workspace,
|
|
35
|
+
]);
|
|
21
36
|
}
|
|
22
37
|
if ((match = /\[\^([\w-]*)$/.exec(prefix))) {
|
|
23
38
|
return footnoteLabels(source).map((label) => completion(label, CompletionItemKind.Reference, match[1], position, 'Footnote'));
|
|
@@ -25,8 +40,32 @@ export function completionAt(source, position) {
|
|
|
25
40
|
if ((match = /\]\[([\w-]*)$/.exec(prefix))) {
|
|
26
41
|
return linkReferenceLabels(source).map((label) => completion(label, CompletionItemKind.Reference, match[1], position, 'Link reference'));
|
|
27
42
|
}
|
|
43
|
+
if ((match = /\[@([\w:.-]*)$/.exec(prefix))) {
|
|
44
|
+
const local = citationLabels(source);
|
|
45
|
+
const workspace = (context.workspaceTokens ?? [])
|
|
46
|
+
.filter((token) => token.declaration && token.kind === 'citation')
|
|
47
|
+
.map((token) => token.key);
|
|
48
|
+
return [...new Set([...local, ...workspace])].map((label) => completion(label, CompletionItemKind.Reference, match[1], position, 'Citation key'));
|
|
49
|
+
}
|
|
50
|
+
if ((match = /\{[^}\n]*\b([\w-]*)$/.exec(prefix))) {
|
|
51
|
+
const attributes = ['#id', '.class', 'align=', 'valign=', 'width=', 'aligns=', 'valigns=', 'widths=',
|
|
52
|
+
'header-rows=', 'header-cols=', 'footer-rows=', 'start=', 'type=', 'title=', 'label='];
|
|
53
|
+
return attributes.map((attribute) => completion(attribute, CompletionItemKind.Property, match[1], position, 'Carve attribute'));
|
|
54
|
+
}
|
|
55
|
+
if ((match = /:(\w*)$/.exec(prefix))) {
|
|
56
|
+
return ['abbr', 'time', 'kbd', 'samp', 'var', 'cite', 'dfn'].map((name) => completion(name, CompletionItemKind.TypeParameter, match[1], position, 'Semantic span'));
|
|
57
|
+
}
|
|
28
58
|
return [];
|
|
29
59
|
}
|
|
60
|
+
function uniqueCompletions(items) {
|
|
61
|
+
const seen = new Set();
|
|
62
|
+
return items.filter((item) => {
|
|
63
|
+
if (seen.has(item.label))
|
|
64
|
+
return false;
|
|
65
|
+
seen.add(item.label);
|
|
66
|
+
return true;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
30
69
|
function completion(value, kind, partial, position, detail) {
|
|
31
70
|
return {
|
|
32
71
|
label: value,
|
|
@@ -57,6 +96,34 @@ function headingIds(source) {
|
|
|
57
96
|
}
|
|
58
97
|
return [...new Set(ids)];
|
|
59
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* The caption ids a `</#…>` can actually RESOLVE, each with what it resolves to
|
|
101
|
+
* - "Figure 2" beside "Figure 2a", so the list distinguishes a group from its
|
|
102
|
+
* panels without the author having to remember which is which.
|
|
103
|
+
*
|
|
104
|
+
* A host that drew NO number is left out. Its id is a real anchor, and a
|
|
105
|
+
* `[text](#id)` fragment link reaches it, but a CROSSREF to it renders as
|
|
106
|
+
* literal text (PART 9 §4c: an unnumbered group's panels are anchors, not
|
|
107
|
+
* caption crossref targets). Every heading id this list offers resolves, and a
|
|
108
|
+
* caption id that did not would be the one entry that quietly does not work.
|
|
109
|
+
*/
|
|
110
|
+
function resolvableCaptionIds(source) {
|
|
111
|
+
let targets;
|
|
112
|
+
try {
|
|
113
|
+
targets = captionTargets(resolve(parse(source, { positions: true })));
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// Parsing may fail mid-edit; offer no ids rather than throwing.
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
const resolvable = [];
|
|
120
|
+
for (const target of targets) {
|
|
121
|
+
if (target.text === null)
|
|
122
|
+
continue;
|
|
123
|
+
resolvable.push({ id: target.id, detail: `${target.text} (${target.kind})` });
|
|
124
|
+
}
|
|
125
|
+
return resolvable;
|
|
126
|
+
}
|
|
60
127
|
function footnoteLabels(source) {
|
|
61
128
|
try {
|
|
62
129
|
const doc = resolve(parse(source));
|
|
@@ -77,6 +144,15 @@ function linkReferenceLabels(source) {
|
|
|
77
144
|
}
|
|
78
145
|
return [...labels];
|
|
79
146
|
}
|
|
147
|
+
function citationLabels(source) {
|
|
148
|
+
const labels = new Set();
|
|
149
|
+
for (const line of source.split(/\r?\n/)) {
|
|
150
|
+
const match = /^\s{0,3}\[@([^\]]+)\]:/.exec(line);
|
|
151
|
+
if (match)
|
|
152
|
+
labels.add(match[1]);
|
|
153
|
+
}
|
|
154
|
+
return [...labels];
|
|
155
|
+
}
|
|
80
156
|
function walkBlocks(nodes, visit) {
|
|
81
157
|
for (const node of nodes) {
|
|
82
158
|
visit(node);
|
package/dist/completion.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GAGnB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAiC,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"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"}
|
package/dist/completion.test.js
CHANGED
|
@@ -32,4 +32,11 @@ test('completion replaces the typed partial', () => {
|
|
|
32
32
|
// Nothing to complete against (no headings) -> empty, but must not throw.
|
|
33
33
|
assert.deepEqual(items, []);
|
|
34
34
|
});
|
|
35
|
+
test('suggests citation keys, semantic spans, and structural attributes', () => {
|
|
36
|
+
assert.deepEqual(labels('[@doc]: Entry\n\n[@do', 2, 4), ['doc']);
|
|
37
|
+
assert.ok(labels(':k', 0, 2).includes('kbd'));
|
|
38
|
+
const attrs = labels('{vali', 0, 5);
|
|
39
|
+
assert.ok(attrs.includes('valign='));
|
|
40
|
+
assert.ok(attrs.includes('valigns='));
|
|
41
|
+
});
|
|
35
42
|
//# sourceMappingURL=completion.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion.test.js","sourceRoot":"","sources":["../src/completion.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAA;AACvC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,IAAY,EAAE,SAAiB,EAAY,EAAE,CAC3E,YAAY,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAErE,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;IACzD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACjC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;IACjC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAA;AACtC,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;IACtD,MAAM,MAAM,GAAG,sBAAsB,CAAA;IACrC,oEAAoE;IACpE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAA;AACzD,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAC5C,MAAM,MAAM,GAAG,8BAA8B,CAAA;IAC7C,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;AAC/C,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC1C,MAAM,MAAM,GAAG,4CAA4C,CAAA;IAC3D,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;AACnD,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,wDAAwD,EAAE,GAAG,EAAE;IAClE,MAAM,MAAM,GAAG,+DAA+D,CAAA;IAC9E,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;AACnD,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC1C,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AACtD,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACjD,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAA;IAC/D,0EAA0E;IAC1E,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;AAC7B,CAAC,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"completion.test.js","sourceRoot":"","sources":["../src/completion.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
import { carveToHtml, lintCarve, parse, resolve } from '@markup-carve/carve';
|
|
4
|
+
import { analyzeCarve } from './analyze.js';
|
|
5
|
+
import { captionTargets, panelLetter } from './captions.js';
|
|
6
|
+
import { completionAt } from './completion.js';
|
|
7
|
+
import { definitionAt } from './definition.js';
|
|
8
|
+
import { hoverAt } from './hover.js';
|
|
9
|
+
import { referencesAt } from './references.js';
|
|
10
|
+
/*
|
|
11
|
+
* A composite figure across the features that resolve an id (PART 9 §4c,
|
|
12
|
+
* markup-carve/carve#1122), plus the diagnostics the clause names.
|
|
13
|
+
*
|
|
14
|
+
* The crossref half of this was NOT a figure_group gap. The server resolved no
|
|
15
|
+
* caption id at all - not a group's, not a panel's, and not the plain captioned
|
|
16
|
+
* figure's that predates the feature - because every crossref feature walked
|
|
17
|
+
* headings only. The `{#fig}` figure below is here for exactly that reason: it
|
|
18
|
+
* is the case that has been broken the longest and is the control for the group
|
|
19
|
+
* cases, so a fix that only taught the walk about `figure_group` fails it.
|
|
20
|
+
*
|
|
21
|
+
* WHERE THE EXPECTED TEXT COMES FROM. The engine, not this file's reading of
|
|
22
|
+
* §4c. `carveToHtml` writes the resolved text into the anchor for each id, and
|
|
23
|
+
* the assertions below compare the server's answer against THAT rather than
|
|
24
|
+
* against a literal - so a letter scheme or a numbering rule that changes
|
|
25
|
+
* upstream fails here instead of diverging quietly in an editor.
|
|
26
|
+
*/
|
|
27
|
+
const DOC = `# Section
|
|
28
|
+
|
|
29
|
+
{#fig}
|
|
30
|
+

|
|
31
|
+
^ Figure #: Plain
|
|
32
|
+
|
|
33
|
+
{#g}
|
|
34
|
+
::: figure
|
|
35
|
+
{#one}
|
|
36
|
+

|
|
37
|
+
^ (a) One
|
|
38
|
+
|
|
39
|
+
A stray paragraph between the panels.
|
|
40
|
+
|
|
41
|
+
{#two}
|
|
42
|
+

|
|
43
|
+
^ (b) Two
|
|
44
|
+
:::
|
|
45
|
+
^ Figure #: Group caption
|
|
46
|
+
|
|
47
|
+
See </#fig>, </#g>, </#one> and </#two>.
|
|
48
|
+
`;
|
|
49
|
+
/**
|
|
50
|
+
* The line the references sit on, and the column of each one. Derived from the
|
|
51
|
+
* document rather than written down, so editing DOC cannot silently move an
|
|
52
|
+
* assertion onto a blank line where every feature correctly answers nothing.
|
|
53
|
+
*/
|
|
54
|
+
const REF_LINE = DOC.split('\n').findIndex((line) => line.startsWith('See '));
|
|
55
|
+
const refColumn = (id) => DOC.split('\n')[REF_LINE].indexOf(`</#${id}>`) + 3;
|
|
56
|
+
/** The text the ENGINE renders for `</#id>`, read off the anchor it writes. */
|
|
57
|
+
const engineRefText = (source, id) => {
|
|
58
|
+
const match = new RegExp(`<a href="#${id}">([^<]*)</a>`).exec(carveToHtml(source));
|
|
59
|
+
return match ? match[1] : null;
|
|
60
|
+
};
|
|
61
|
+
const targetFor = (source, id) => captionTargets(resolve(parse(source, { positions: true }))).find((t) => t.id === id);
|
|
62
|
+
test('every caption id resolves to the text the engine renders for it', () => {
|
|
63
|
+
for (const id of ['fig', 'g', 'one', 'two']) {
|
|
64
|
+
assert.equal(targetFor(DOC, id)?.text, engineRefText(DOC, id), `crossref text for #${id} disagrees with the rendered anchor`);
|
|
65
|
+
}
|
|
66
|
+
// Not merely "equal to each other": the group's own reference carries no
|
|
67
|
+
// letter and its panels do, which is the rule under test.
|
|
68
|
+
assert.equal(engineRefText(DOC, 'g'), 'Figure 2');
|
|
69
|
+
assert.equal(engineRefText(DOC, 'one'), 'Figure 2a');
|
|
70
|
+
assert.equal(engineRefText(DOC, 'two'), 'Figure 2b');
|
|
71
|
+
});
|
|
72
|
+
test('a stray block between panels does not take a letter', () => {
|
|
73
|
+
// The paragraph sits between the two panels. If the walk counted children
|
|
74
|
+
// rather than PANELS, the second panel would be "Figure 2c".
|
|
75
|
+
assert.equal(targetFor(DOC, 'two')?.text, 'Figure 2b');
|
|
76
|
+
});
|
|
77
|
+
test('panel letters run a..z then aa', () => {
|
|
78
|
+
assert.deepEqual([0, 1, 25, 26, 27, 51, 52].map(panelLetter), [
|
|
79
|
+
'a',
|
|
80
|
+
'b',
|
|
81
|
+
'z',
|
|
82
|
+
'aa',
|
|
83
|
+
'ab',
|
|
84
|
+
'az',
|
|
85
|
+
'ba',
|
|
86
|
+
]);
|
|
87
|
+
});
|
|
88
|
+
test('an unnumbered group registers anchors but no crossref text', () => {
|
|
89
|
+
const source = `{#ug}\n::: figure\n{#u1}\n\n^ (a) U\n:::\n^ No number here\n\nSee </#ug> and </#u1>.\n`;
|
|
90
|
+
assert.equal(targetFor(source, 'ug')?.text, null);
|
|
91
|
+
assert.equal(targetFor(source, 'u1')?.text, null);
|
|
92
|
+
// The engine agrees: it leaves both references as literal text rather than
|
|
93
|
+
// linking them, which is what "not a caption crossref target" means (§4c).
|
|
94
|
+
assert.equal(engineRefText(source, 'ug'), null);
|
|
95
|
+
assert.equal(engineRefText(source, 'u1'), null);
|
|
96
|
+
});
|
|
97
|
+
test('go-to-definition on a crossref reaches the host, panel or not', () => {
|
|
98
|
+
// `</#fig>` is the control: a captioned figure, no group involved, and it
|
|
99
|
+
// jumped nowhere before this.
|
|
100
|
+
const hostLine = (id) => definitionAt('file:///d.crv', DOC, { line: REF_LINE, character: refColumn(id) })?.range.start.line;
|
|
101
|
+
assert.equal(hostLine('fig'), 3);
|
|
102
|
+
assert.equal(hostLine('g'), 7);
|
|
103
|
+
assert.equal(hostLine('one'), 9);
|
|
104
|
+
});
|
|
105
|
+
test('a crossref hover names what the id resolves to', () => {
|
|
106
|
+
const text = (id) => {
|
|
107
|
+
const hover = hoverAt(DOC, { line: REF_LINE, character: refColumn(id) });
|
|
108
|
+
return typeof hover?.contents === 'object' && 'value' in hover.contents ? hover.contents.value : '';
|
|
109
|
+
};
|
|
110
|
+
assert.match(text('one'), /Figure 2a/);
|
|
111
|
+
assert.match(text('one'), /panel/);
|
|
112
|
+
assert.match(text('g'), /Figure 2/);
|
|
113
|
+
// CONTROL. Before this, no `heading_ref` case existed and the lexical rules
|
|
114
|
+
// took the `#` inside the reference, so every crossref hovered as a heading.
|
|
115
|
+
assert.doesNotMatch(text('one'), /create section headings/);
|
|
116
|
+
});
|
|
117
|
+
test('find-references pairs a panel id with its usages', () => {
|
|
118
|
+
const locations = referencesAt('file:///d.crv', DOC, { line: REF_LINE, character: refColumn('one') }, { includeDeclaration: true });
|
|
119
|
+
assert.deepEqual(locations?.map((location) => location.range.start.line), [9, REF_LINE]);
|
|
120
|
+
});
|
|
121
|
+
test('crossref completion offers caption ids beside heading ids', () => {
|
|
122
|
+
const source = DOC.replace('See </#fig>, </#g>, </#one> and </#two>.', 'See </#');
|
|
123
|
+
const items = completionAt(source, { line: REF_LINE, character: 7 });
|
|
124
|
+
const detail = (label) => items.find((i) => i.label === label)?.detail;
|
|
125
|
+
assert.equal(detail('Section'), 'Heading id');
|
|
126
|
+
assert.equal(detail('fig'), 'Figure 1 (figure)');
|
|
127
|
+
assert.equal(detail('g'), 'Figure 2 (composite figure)');
|
|
128
|
+
assert.equal(detail('one'), 'Figure 2a (panel)');
|
|
129
|
+
assert.equal(detail('two'), 'Figure 2b (panel)');
|
|
130
|
+
});
|
|
131
|
+
test('an unnumbered host is not offered as a crossref target', () => {
|
|
132
|
+
// Every id `</#` offers has to RESOLVE. An unnumbered host is a real anchor
|
|
133
|
+
// and a fragment link reaches it, but a crossref to it renders as literal
|
|
134
|
+
// text, so offering it here would be the one entry in the list that does not
|
|
135
|
+
// work - the heading ids beside it all do.
|
|
136
|
+
const source = `{#ug}\n::: figure\n{#u1}\n\n^ (a) U\n:::\n^ No number here\n\nSee </#`;
|
|
137
|
+
const labels = completionAt(source, { line: 8, character: 7 }).map((item) => item.label);
|
|
138
|
+
assert.deepEqual(labels, []);
|
|
139
|
+
});
|
|
140
|
+
test('find-references works from the declaration as well as from a usage', () => {
|
|
141
|
+
// A heading declares its id on its own line; a captioned host declares it on
|
|
142
|
+
// the block-attribute line ABOVE itself. Both are where an author puts the
|
|
143
|
+
// cursor to ask "what points at this?".
|
|
144
|
+
const fromAttributeLine = referencesAt('file:///d.crv', DOC, { line: 6, character: 2 }, {
|
|
145
|
+
includeDeclaration: false,
|
|
146
|
+
});
|
|
147
|
+
const fromHostLine = referencesAt('file:///d.crv', DOC, { line: 7, character: 2 }, {
|
|
148
|
+
includeDeclaration: false,
|
|
149
|
+
});
|
|
150
|
+
assert.deepEqual(fromAttributeLine?.map((location) => location.range.start.line), [REF_LINE]);
|
|
151
|
+
assert.deepEqual(fromHostLine?.map((location) => location.range.start.line), [REF_LINE]);
|
|
152
|
+
});
|
|
153
|
+
test('a declaration inside a container still declares', () => {
|
|
154
|
+
// The id's line is not always a bare `{#id}` at column 0. A shape test on it
|
|
155
|
+
// reads like a safety check and is not one - a host only has an id because a
|
|
156
|
+
// block-attribute line gave it one - so it can only reject a right answer.
|
|
157
|
+
const quoted = '> {#fig}\n> \n> ^ Figure #: A\n\nSee </#fig>.\n';
|
|
158
|
+
assert.deepEqual(referencesAt('file:///d.crv', quoted, { line: 0, character: 3 }, { includeDeclaration: false })
|
|
159
|
+
?.map((location) => location.range.start.line), [4]);
|
|
160
|
+
});
|
|
161
|
+
test('a line that declares no id declares nothing', () => {
|
|
162
|
+
// CONTROL. The lookup keys on hosts that CARRY an id, not on hosts. An
|
|
163
|
+
// uncaptioned-id figure has no entry, so the prose above it is just prose.
|
|
164
|
+
assert.equal(referencesAt('file:///d.crv', 'Prose.\n\n^ Figure #: A\n', { line: 0, character: 2 }, {
|
|
165
|
+
includeDeclaration: false,
|
|
166
|
+
}), null);
|
|
167
|
+
// And a line nowhere near a host answers nothing either.
|
|
168
|
+
assert.equal(referencesAt('file:///d.crv', DOC, { line: 12, character: 2 }, { includeDeclaration: false }), null);
|
|
169
|
+
});
|
|
170
|
+
test('a construct on the declaration line still wins', () => {
|
|
171
|
+
// CONTROL for the declaration lookup, which is matched by LINE and so
|
|
172
|
+
// answers for every column on it. A host line can carry a reference image,
|
|
173
|
+
// and asking on its label must reach the link-reference definition rather
|
|
174
|
+
// than the figure that happens to wrap it.
|
|
175
|
+
const source = '{#fig}\n![alt][img]\n^ Figure #: C\n\n[img]: pic.png\n\nAgain [x][img].\n';
|
|
176
|
+
const onLabel = referencesAt('file:///d.crv', source, { line: 1, character: 8 }, {
|
|
177
|
+
includeDeclaration: true,
|
|
178
|
+
});
|
|
179
|
+
assert.deepEqual(onLabel?.map((location) => location.range.start.line), [1, 4, 6]);
|
|
180
|
+
// The same line still declares the figure where nothing else claims the
|
|
181
|
+
// cursor - here, on the `!` that opens the image.
|
|
182
|
+
const onHost = referencesAt('file:///d.crv', source, { line: 0, character: 2 }, {
|
|
183
|
+
includeDeclaration: false,
|
|
184
|
+
});
|
|
185
|
+
assert.deepEqual(onHost?.map((location) => location.range.start.line), []);
|
|
186
|
+
});
|
|
187
|
+
test('a collapsed reference is not a usage of a caption id', () => {
|
|
188
|
+
// `[foo][]` falls back to the implicit HEADING target and to nothing else
|
|
189
|
+
// (PART 9R R1): beside a figure `{#foo}` it renders as literal text, so
|
|
190
|
+
// reporting it as a usage would be a reference the author cannot follow.
|
|
191
|
+
const source = '{#foo}\n\n^ Figure #: Foo\n\nSee [foo][] and </#foo>.\n';
|
|
192
|
+
const locations = referencesAt('file:///d.crv', source, { line: 4, character: 22 }, {
|
|
193
|
+
includeDeclaration: false,
|
|
194
|
+
});
|
|
195
|
+
assert.deepEqual(locations?.map((location) => location.range.start.character), [16]);
|
|
196
|
+
});
|
|
197
|
+
test('a collapsed reference IS a usage of a heading id', () => {
|
|
198
|
+
// CONTROL. The scan is not removed, it is scoped: the same spelling still
|
|
199
|
+
// reaches a heading, which is the target it actually resolves to.
|
|
200
|
+
const source = '# Foo\n\nSee [foo][] and </#Foo>.\n';
|
|
201
|
+
const locations = referencesAt('file:///d.crv', source, { line: 2, character: 20 }, {
|
|
202
|
+
includeDeclaration: false,
|
|
203
|
+
});
|
|
204
|
+
assert.deepEqual(locations?.map((location) => location.range.start.character), [16, 4]);
|
|
205
|
+
});
|
|
206
|
+
test('the outline carries the group and nests its panels', () => {
|
|
207
|
+
const symbols = analyzeCarve(DOC).symbols;
|
|
208
|
+
assert.equal(symbols.length, 1, 'the heading is still the only root');
|
|
209
|
+
const group = symbols[0].children?.find((child) => child.name.startsWith('Figure 2'));
|
|
210
|
+
assert.ok(group, `no group symbol under the heading: ${JSON.stringify(symbols[0].children)}`);
|
|
211
|
+
assert.equal(group.name, 'Figure 2: Group caption');
|
|
212
|
+
assert.equal(group.detail, '2 panels');
|
|
213
|
+
assert.deepEqual(group.children?.map((panel) => panel.name), ['(a) One', '(b) Two']);
|
|
214
|
+
});
|
|
215
|
+
test('a heading inside a panel stays in the outline', () => {
|
|
216
|
+
// CONTROL for the group's own entry. A panel yields no outline entry of its
|
|
217
|
+
// own, but the walk still descends through it: a panel can wrap a quote
|
|
218
|
+
// holding headings, and those belong to the section the group sits in - which
|
|
219
|
+
// is where they were before the group had an entry at all.
|
|
220
|
+
const symbols = analyzeCarve('# Section\n\n::: figure\n> ## Inside a panel\n>\n> Quoted.\n^ (a) A\n:::\n^ Figure #: g\n').symbols;
|
|
221
|
+
assert.deepEqual(symbols[0].children?.map((child) => child.name), ['Figure 1: g', 'Inside a panel']);
|
|
222
|
+
});
|
|
223
|
+
test('a group with no caption is still an outline entry, named for what it is', () => {
|
|
224
|
+
const symbols = analyzeCarve('::: figure\n\n^ (a) A\n:::\n').symbols;
|
|
225
|
+
assert.deepEqual(symbols.map((symbol) => symbol.name), ['Composite figure']);
|
|
226
|
+
assert.equal(symbols[0].detail, '1 panel');
|
|
227
|
+
});
|
|
228
|
+
test('an uncaptioned panel falls back to the letter a crossref would use', () => {
|
|
229
|
+
const symbols = analyzeCarve('::: figure\n| a |\n\n| b |\n:::\n^ Figure #: g\n').symbols;
|
|
230
|
+
assert.deepEqual(symbols[0].children?.map((panel) => panel.name), ['Panel a', 'Panel b']);
|
|
231
|
+
});
|
|
232
|
+
test('a heading is still a heading, wherever it sits relative to a group', () => {
|
|
233
|
+
// CONTROL for the outline change. A group takes no heading level, so it must
|
|
234
|
+
// not pop the stack: the section after it stays a sibling of the one before.
|
|
235
|
+
const symbols = analyzeCarve('# One\n\n::: figure\n\n^ (a) A\n:::\n\n## Under one\n\n# Two\n').symbols;
|
|
236
|
+
assert.deepEqual(symbols.map((symbol) => symbol.name), ['One', 'Two']);
|
|
237
|
+
assert.deepEqual(symbols[0].children?.map((child) => child.name), ['Composite figure', 'Under one']);
|
|
238
|
+
});
|
|
239
|
+
/*
|
|
240
|
+
* The five §4c findings. The server derives none of them - it publishes what
|
|
241
|
+
* `lintCarve` reports - so what is pinned here is that the passthrough works
|
|
242
|
+
* and that the engine still emits each id under the pinned build. Nothing
|
|
243
|
+
* asserted it before, so a passthrough that stopped would have been silent.
|
|
244
|
+
*/
|
|
245
|
+
const LINT_CASES = [
|
|
246
|
+
['figure-group-nested', '::: figure\n::: figure\nBody.\n:::\n:::\n^ Figure #: outer\n'],
|
|
247
|
+
['figure-group-opener-metadata', '::: figure "T"\n\n^ (a) A\n:::\n'],
|
|
248
|
+
['figure-group-panel-number', '::: figure\n\n^ Figure #: panel\n:::\n^ Figure #: group\n'],
|
|
249
|
+
['figure-group-empty', '::: figure\nJust text.\n:::\n^ Figure #: g\n'],
|
|
250
|
+
['figure-group-single-panel', '::: figure\n\n^ (a) A\n:::\n^ Figure #: g\n'],
|
|
251
|
+
];
|
|
252
|
+
for (const [code, source] of LINT_CASES) {
|
|
253
|
+
test(`${code} reaches the server's diagnostics`, () => {
|
|
254
|
+
assert.ok(lintCarve(source).some((warning) => warning.rule === code), `the pinned engine no longer emits ${code}`);
|
|
255
|
+
assert.ok(analyzeCarve(source).diagnostics.some((diagnostic) => diagnostic.code === code), `${code} did not reach the server: ${JSON.stringify(analyzeCarve(source).diagnostics.map((d) => d.code))}`);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
test('a well-formed group reports none of them', () => {
|
|
259
|
+
// CONTROL. Every case above differs from this document in one line, so a
|
|
260
|
+
// passthrough that published a fixed list would look identical up there.
|
|
261
|
+
const clean = '::: figure\n\n^ (a) A\n\n\n^ (b) B\n:::\n^ Figure #: g\n';
|
|
262
|
+
const codes = analyzeCarve(clean).diagnostics.map((diagnostic) => diagnostic.code);
|
|
263
|
+
assert.deepEqual(codes.filter((code) => String(code).startsWith('figure-group-')), []);
|
|
264
|
+
});
|
|
265
|
+
//# sourceMappingURL=composite-figure-crossref.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composite-figure-crossref.test.js","sourceRoot":"","sources":["../src/composite-figure-crossref.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
import { parse, resolve } from '@markup-carve/carve';
|
|
4
|
+
import { completionAt } from './completion.js';
|
|
5
|
+
import { foldingRanges } from './folding.js';
|
|
6
|
+
import { hoverAt } from './hover.js';
|
|
7
|
+
import { semanticTokens } from './semantic.js';
|
|
8
|
+
/*
|
|
9
|
+
* Composite figures across the four features that read block types (PART 9 §4c,
|
|
10
|
+
* markup-carve/carve#1215).
|
|
11
|
+
*
|
|
12
|
+
* A BARE `::: figure` opener - the fence, its separator, the kind word, and
|
|
13
|
+
* NOTHING else - is ONE figure of ordered panels, and the engine normalizes it
|
|
14
|
+
* to a `figure_group` node. An opener carrying a quoted title or a `[label]` is
|
|
15
|
+
* not that production at all and stays a generic container.
|
|
16
|
+
*
|
|
17
|
+
* Every feature here switches on `node.type` with a default that does nothing,
|
|
18
|
+
* so a node type the engine grew and the server never learned is INVISIBLE
|
|
19
|
+
* rather than a type error: the container simply stops folding, hovering and
|
|
20
|
+
* tokenizing, and every existing test stays green. That is the failure this file
|
|
21
|
+
* is here to catch, which is why the first test asserts the engine's shape
|
|
22
|
+
* directly - if the dependency stops producing `figure_group`, this file should
|
|
23
|
+
* say so plainly rather than reporting four unrelated feature failures.
|
|
24
|
+
*/
|
|
25
|
+
const GROUP = '::: figure\n\n^ (a) One\n:::\n^ Figure #: Group caption\n';
|
|
26
|
+
const TITLED = '::: figure "A titled figure div"\n\n^ (a) One\n:::\n';
|
|
27
|
+
const LABELLED = '::: figure [g]\nBody.\n:::\n';
|
|
28
|
+
const topLevelTypes = (source) => resolve(parse(source, { positions: true })).children.map((node) => node.type);
|
|
29
|
+
test('the pinned engine normalizes a bare figure fence to a figure_group', () => {
|
|
30
|
+
assert.deepEqual(topLevelTypes(GROUP), ['figure_group']);
|
|
31
|
+
});
|
|
32
|
+
test('a title or a label leaves it a generic container', () => {
|
|
33
|
+
// The control for every case below. These two differ from GROUP only in the
|
|
34
|
+
// tail of one line, so a reading that fires on the kind word alone would
|
|
35
|
+
// report them as groups and nothing else here would notice.
|
|
36
|
+
assert.deepEqual(topLevelTypes(TITLED), ['admonition']);
|
|
37
|
+
assert.deepEqual(topLevelTypes(LABELLED), ['admonition']);
|
|
38
|
+
});
|
|
39
|
+
test('a composite figure folds', () => {
|
|
40
|
+
const ranges = foldingRanges(GROUP);
|
|
41
|
+
assert.ok(ranges.some((range) => range.startLine === 0 && range.endLine >= 3), `no fold for the group: ${JSON.stringify(ranges)}`);
|
|
42
|
+
});
|
|
43
|
+
test('the opener carries the reserved kind word as a type token', () => {
|
|
44
|
+
const opener = semanticTokens(GROUP).filter((token) => token.line === 0);
|
|
45
|
+
assert.ok(opener.length > 0, 'the opener line produced no token at all');
|
|
46
|
+
assert.equal(opener[0].type, 'type');
|
|
47
|
+
// `::: figure` - the whole reserved opener, not just the fence run.
|
|
48
|
+
assert.equal(opener[0].character, 0);
|
|
49
|
+
assert.equal(opener[0].length, 10);
|
|
50
|
+
});
|
|
51
|
+
test('the group caption after the closing fence is tokenized', () => {
|
|
52
|
+
// Line 4, the `^ ` line BELOW the closer. It is the group's caption and it
|
|
53
|
+
// sits outside the container, which is the one placement §4c adds: read from
|
|
54
|
+
// any child instead of from the group, and this line has no token at all.
|
|
55
|
+
assert.ok(semanticTokens(GROUP).some((token) => token.line === 4), 'the caption line below the closing fence produced no token');
|
|
56
|
+
});
|
|
57
|
+
test('hovering a composite figure describes the group, not an admonition', () => {
|
|
58
|
+
const hover = hoverAt(GROUP, { line: 0, character: 4 });
|
|
59
|
+
const text = typeof hover?.contents === 'object' && 'value' in hover.contents ? hover.contents.value : '';
|
|
60
|
+
assert.match(text, /Composite Figure/);
|
|
61
|
+
});
|
|
62
|
+
test('a titled figure opener still hovers as an admonition', () => {
|
|
63
|
+
const hover = hoverAt(TITLED, { line: 0, character: 4 });
|
|
64
|
+
const text = typeof hover?.contents === 'object' && 'value' in hover.contents ? hover.contents.value : '';
|
|
65
|
+
assert.match(text, /Admonition/);
|
|
66
|
+
});
|
|
67
|
+
test('a colon fence offers figure, and not as a ninth admonition kind', () => {
|
|
68
|
+
const items = completionAt(':::', { line: 0, character: 3 });
|
|
69
|
+
const figure = items.find((item) => item.label === 'figure');
|
|
70
|
+
assert.ok(figure, `figure is not offered: ${items.map((i) => i.label).join(',')}`);
|
|
71
|
+
assert.equal(figure.detail, 'Composite figure');
|
|
72
|
+
// The eight are still there and still say what they are.
|
|
73
|
+
const note = items.find((item) => item.label === 'note');
|
|
74
|
+
assert.equal(note?.detail, 'Admonition kind');
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=composite-figure.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composite-figure.test.js","sourceRoot":"","sources":["../src/composite-figure.test.ts"],"names":[],"mappings":"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"}
|
package/dist/definition.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { type Location, type Position } from 'vscode-languageserver/node.js';
|
|
2
|
+
import type { IncludeOptions } from './includes.js';
|
|
2
3
|
/**
|
|
3
4
|
* Go-to-definition for Carve constructs:
|
|
4
5
|
*
|
|
5
|
-
* - Cross-reference `</#id>` -> the heading whose generated id is `id
|
|
6
|
+
* - Cross-reference `</#id>` -> the heading whose generated id is `id`,
|
|
7
|
+
* or the captioned host carrying it
|
|
6
8
|
* - Fragment link `[text](#id)` -> same (href starts with `#`)
|
|
7
9
|
* - Footnote ref `[^name]` -> the `[^name]:` definition line
|
|
8
10
|
* - Link reference `[text][ref]` -> the `[ref]:` definition line
|
|
9
11
|
* - Citation `[@key]` -> the `[@key]:` definition line
|
|
10
12
|
* - Wikilink `[[Page]]` -> heading whose text matches Page (best-effort)
|
|
11
13
|
*/
|
|
12
|
-
export declare function definitionAt(uri: string, source: string, position: Position): Location | null;
|
|
14
|
+
export declare function definitionAt(uri: string, source: string, position: Position, includes?: IncludeOptions): Location | null;
|