@faubulous/mentor-rdf-serializers 1.1.4 → 1.2.0
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 +48 -534
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -18
- package/dist/index.js.map +1 -1
- package/dist/statement-group.d.ts +126 -0
- package/dist/statement-group.d.ts.map +1 -0
- package/dist/statement-group.js +271 -0
- package/dist/statement-group.js.map +1 -0
- package/dist/statement-serializer.d.ts +146 -0
- package/dist/statement-serializer.d.ts.map +1 -0
- package/dist/statement-serializer.js +216 -0
- package/dist/statement-serializer.js.map +1 -0
- package/dist/trig/serializer.d.ts.map +1 -1
- package/dist/trig/serializer.js +6 -2
- package/dist/trig/serializer.js.map +1 -1
- package/dist/turtle/serializer.d.ts.map +1 -1
- package/dist/turtle/serializer.js +6 -2
- package/dist/turtle/serializer.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1 -0
- package/dist/utils.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,82 +1,39 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Mentor RDF Serializers
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@faubulous/mentor-rdf-serializers)
|
|
4
|
+
[](https://www.npmjs.com/package/@faubulous/mentor-rdf-parsers)
|
|
5
|
+
[](https://opensource.org/licenses/LGPL-2.1)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://www.w3.org/TR/rdf12-concepts/)
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- **Multiple Formats**: N-Triples, N-Quads, Turtle, TriG, N3, JSON-LD
|
|
8
|
-
- **SPARQL Formatting**: Format SPARQL queries and updates with comment preservation
|
|
9
|
-
- **RDF 1.2 Support**: Full support for RDF 1.2 features including:
|
|
10
|
-
- Triple Terms (`<<( s p o )>>`)
|
|
11
|
-
- Reified Triples (`<< s p o >>`)
|
|
12
|
-
- Annotations (`{| p o |}`)
|
|
13
|
-
- Language direction (`@en--ltr`, `@ar--rtl`)
|
|
14
|
-
- **Advanced Formatting Options**: Control line width, alignment, blank node style, and more
|
|
15
|
-
- **Comment Preservation**: Preserve comments when reformatting source files
|
|
16
|
-
- **Token-based Serialization**: Serialize directly from parser tokens, preserving blank node IDs
|
|
17
|
-
- **Sorting Strategies**: Pluggable sorting with built-in alphabetical and priority-based strategies
|
|
18
|
-
- **IDE Integration**: Designed for code formatting and partial document serialization
|
|
19
|
-
- **Prefix Handling**: Automatic prefix compaction and expansion
|
|
20
|
-
- **Configurable Output**: Pretty printing, sorting, grouping options
|
|
21
|
-
|
|
22
|
-
## Architecture
|
|
23
|
-
|
|
24
|
-
The `mentor-rdf-serializers` package is designed to work seamlessly with `mentor-rdf-parsers`, forming a complete round-trip pipeline for RDF processing in IDEs and editors.
|
|
25
|
-
|
|
26
|
-
```mermaid
|
|
27
|
-
flowchart LR
|
|
28
|
-
subgraph Source
|
|
29
|
-
A[RDF text (Turtle, TriG, ...)]
|
|
30
|
-
B[SPARQL text]
|
|
31
|
-
C[RDF/JS quads]
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
subgraph mentor-rdf-parsers
|
|
35
|
-
P1[Parser]
|
|
36
|
-
T1[Tokens]
|
|
37
|
-
Q1[Quads]
|
|
9
|
+
**A TypeScript library for serializing and formatting RDF and SPARQL, built for IDE integration.**
|
|
38
10
|
|
|
39
|
-
|
|
40
|
-
P1 --> T1
|
|
41
|
-
P1 --> Q1
|
|
11
|
+
Designed as the counterpart to [@faubulous/mentor-rdf-parsers](https://github.com/faubulous/mentor-rdf-parsers), this library provides RDF serialization and SPARQL formatting with first-class support for editor workflows such as document formatting, range formatting, comment preservation, and configurable output styles.
|
|
42
12
|
|
|
43
|
-
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
subgraph mentor-rdf-serializers
|
|
47
|
-
S1[Quad serializers\n(Turtle, N-Triples, ...)]
|
|
48
|
-
TS[TokenSerializer]
|
|
49
|
-
SF[SparqlFormatter]
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
subgraph Output
|
|
53
|
-
O1[Serialized / formatted RDF]
|
|
54
|
-
O2[Formatted SPARQL]
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
C --> S1 --> O1
|
|
58
|
-
Q1 --> S1
|
|
59
|
-
T1 --> TS --> O1
|
|
60
|
-
T2 --> SF --> O2
|
|
13
|
+
## Features
|
|
61
14
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
15
|
+
| | |
|
|
16
|
+
|---|---|
|
|
17
|
+
| **Multi-Format Output** | Serialize to N-Triples, N-Quads, Turtle, TriG, N3, and JSON-LD |
|
|
18
|
+
| **SPARQL Formatting** | Format queries and updates with keyword casing, alignment, and comment preservation |
|
|
19
|
+
| **RDF 1.2** | Triple terms (`<<( s p o )>>`), reified triples, annotations, and language direction |
|
|
20
|
+
| **Sorting Strategies** | Alphabetical, by-type, semantic, and priority-based quad ordering |
|
|
21
|
+
| **Comment Preservation** | Token-based serialization keeps comments attached to their statements |
|
|
22
|
+
| **Token Serialization** | Serialize directly from parser tokens to preserve blank node IDs and source layout |
|
|
23
|
+
| **Configurable Layout** | Line width, predicate alignment, blank node style, object list wrapping, and more |
|
|
24
|
+
| **IDE-Ready** | Partial document serialization, range formatting, and VS Code integration examples |
|
|
65
25
|
|
|
66
|
-
##
|
|
26
|
+
## Quick Start
|
|
67
27
|
|
|
68
28
|
```bash
|
|
69
29
|
npm install @faubulous/mentor-rdf-serializers
|
|
70
30
|
```
|
|
71
31
|
|
|
72
|
-
## Quick Start
|
|
73
|
-
|
|
74
32
|
```typescript
|
|
75
33
|
import { TurtleSerializer } from '@faubulous/mentor-rdf-serializers';
|
|
76
34
|
import DataFactory from '@rdfjs/data-model';
|
|
77
35
|
|
|
78
36
|
const serializer = new TurtleSerializer();
|
|
79
|
-
|
|
80
37
|
const quads = [
|
|
81
38
|
DataFactory.quad(
|
|
82
39
|
DataFactory.namedNode('http://example.org/subject'),
|
|
@@ -90,493 +47,50 @@ const quads = [
|
|
|
90
47
|
)
|
|
91
48
|
];
|
|
92
49
|
|
|
93
|
-
|
|
50
|
+
console.log(serializer.serialize(quads, {
|
|
94
51
|
prefixes: {
|
|
95
52
|
'ex': 'http://example.org/',
|
|
96
53
|
'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
|
|
97
54
|
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
console.log(turtle);
|
|
101
|
-
// @prefix ex: <http://example.org/> .
|
|
102
|
-
// @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
|
103
|
-
//
|
|
104
|
-
// ex:subject a ex:Class ;
|
|
105
|
-
// ex:name "Example"@en .
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Serializers
|
|
109
|
-
|
|
110
|
-
### N-Triples
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
import { NTriplesSerializer } from '@faubulous/mentor-rdf-serializers';
|
|
114
|
-
|
|
115
|
-
const serializer = new NTriplesSerializer();
|
|
116
|
-
const output = serializer.serialize(quads, { sort: true });
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### N-Quads
|
|
120
|
-
|
|
121
|
-
```typescript
|
|
122
|
-
import { NQuadsSerializer } from '@faubulous/mentor-rdf-serializers';
|
|
123
|
-
|
|
124
|
-
const serializer = new NQuadsSerializer();
|
|
125
|
-
const output = serializer.serialize(quads);
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### Turtle
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
import { TurtleSerializer } from '@faubulous/mentor-rdf-serializers';
|
|
132
|
-
|
|
133
|
-
const serializer = new TurtleSerializer();
|
|
134
|
-
const output = serializer.serialize(quads, {
|
|
135
|
-
prefixes: { 'ex': 'http://example.org/' },
|
|
136
|
-
baseIri: 'http://example.org/',
|
|
137
|
-
groupBySubject: true,
|
|
138
|
-
sort: true
|
|
139
|
-
});
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### TriG
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
import { TriGSerializer } from '@faubulous/mentor-rdf-serializers';
|
|
146
|
-
|
|
147
|
-
const serializer = new TriGSerializer();
|
|
148
|
-
const output = serializer.serialize(quadsWithGraphs, {
|
|
149
|
-
prefixes: { 'ex': 'http://example.org/' }
|
|
150
|
-
});
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### N3
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
import { N3Serializer } from '@faubulous/mentor-rdf-serializers';
|
|
157
|
-
|
|
158
|
-
const serializer = new N3Serializer();
|
|
159
|
-
const output = serializer.serialize(quads); // Supports formulas and implications
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### JSON-LD
|
|
163
|
-
|
|
164
|
-
```typescript
|
|
165
|
-
import { JsonLdSerializer } from '@faubulous/mentor-rdf-serializers';
|
|
166
|
-
|
|
167
|
-
const serializer = new JsonLdSerializer();
|
|
168
|
-
const output = serializer.serialize(quads, {
|
|
169
|
-
prefixes: { 'ex': 'http://example.org/' },
|
|
170
|
-
useTypeShorthand: true,
|
|
171
|
-
useIdShorthand: true,
|
|
172
|
-
compactArrays: true,
|
|
173
|
-
prettyPrint: true
|
|
174
|
-
});
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
## SPARQL Formatting
|
|
178
|
-
|
|
179
|
-
```typescript
|
|
180
|
-
import { SparqlFormatter } from '@faubulous/mentor-rdf-serializers';
|
|
181
|
-
|
|
182
|
-
const formatter = new SparqlFormatter();
|
|
183
|
-
|
|
184
|
-
// Format a SELECT query
|
|
185
|
-
const selectResult = formatter.formatFromText(`
|
|
186
|
-
SELECT ?s ?p ?o WHERE { ?s ?p ?o . FILTER(?o > 10) }
|
|
187
|
-
`, {
|
|
188
|
-
uppercaseKeywords: true,
|
|
189
|
-
alignPatterns: true,
|
|
190
|
-
sameBraceLine: true,
|
|
191
|
-
separateClauses: true,
|
|
192
|
-
maxLineWidth: 80
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
console.log(selectResult.output);
|
|
196
|
-
|
|
197
|
-
// Format a SPARQL UPDATE (same API)
|
|
198
|
-
const updateResult = formatter.formatFromText(`
|
|
199
|
-
INSERT DATA { <http://example.org/s> <http://example.org/p> "value" }
|
|
200
|
-
`, {
|
|
201
|
-
indent: ' ',
|
|
202
|
-
uppercaseKeywords: true
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
console.log(updateResult.output);
|
|
206
|
-
|
|
207
|
-
// Comments are preserved
|
|
208
|
-
const withComments = formatter.formatFromText(`
|
|
209
|
-
# Find all people
|
|
210
|
-
SELECT ?person WHERE {
|
|
211
|
-
?person a <http://example.org/Person> . # Match persons
|
|
212
|
-
}
|
|
213
|
-
`);
|
|
214
|
-
|
|
215
|
-
console.log(withComments.output); // Comments remain in the formatted output
|
|
55
|
+
}));
|
|
216
56
|
```
|
|
217
57
|
|
|
218
|
-
## Token-based Serialization
|
|
219
|
-
|
|
220
|
-
For IDE integration, you can serialize directly from parser tokens, which preserves blank node IDs and comments from the source document.
|
|
221
|
-
|
|
222
|
-
```typescript
|
|
223
|
-
import { TokenSerializer } from '@faubulous/mentor-rdf-serializers';
|
|
224
|
-
import { TurtleParser } from '@faubulous/mentor-rdf-parsers';
|
|
225
|
-
|
|
226
|
-
const parser = new TurtleParser();
|
|
227
|
-
const parseResult = parser.parse(sourceDocument);
|
|
228
|
-
|
|
229
|
-
const tokenSerializer = new TokenSerializer();
|
|
230
|
-
|
|
231
|
-
// Serialize all tokens
|
|
232
|
-
const output = tokenSerializer.serialize(parseResult.tokens, {
|
|
233
|
-
preserveBlankNodeIds: true,
|
|
234
|
-
preserveComments: true // Keeps comments in output
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
// Serialize only a specific range (for range formatting)
|
|
238
|
-
const rangeOutput = tokenSerializer.serializeRange(
|
|
239
|
-
parseResult.tokens,
|
|
240
|
-
startOffset,
|
|
241
|
-
endOffset,
|
|
242
|
-
{ preserveComments: true }
|
|
243
|
-
);
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
## Serialization Options
|
|
247
|
-
|
|
248
|
-
### Common Options
|
|
249
|
-
|
|
250
|
-
| Option | Type | Description |
|
|
251
|
-
|--------|------|-------------|
|
|
252
|
-
| `prefixes` | `Record<string, string>` | Prefix mappings for compacting IRIs |
|
|
253
|
-
| `baseIri` | `string` | Base IRI for relative references |
|
|
254
|
-
| `sort` | `boolean` | Sort output alphabetically |
|
|
255
|
-
| `prettyPrint` | `boolean` | Enable pretty formatting |
|
|
256
|
-
|
|
257
|
-
### Turtle/TriG Options
|
|
258
|
-
|
|
259
|
-
| Option | Type | Default | Description |
|
|
260
|
-
|--------|------|---------|-------------|
|
|
261
|
-
| `groupBySubject` | `boolean` | `true` | Group triples by subject |
|
|
262
|
-
| `usePrefixedNames` | `boolean` | `true` | Use prefixed names where possible |
|
|
263
|
-
| `useShorthandTypes` | `boolean` | `true` | Use `a` for `rdf:type` |
|
|
264
|
-
| `useLongStrings` | `boolean` | `true` | Use `"""` for multiline strings |
|
|
265
|
-
| `useNumericShorthands` | `boolean` | `true` | Use numeric literals without quotes |
|
|
266
|
-
|
|
267
|
-
### Formatting Options
|
|
268
|
-
|
|
269
|
-
These options control the visual layout of Turtle, TriG, and SPARQL output:
|
|
270
|
-
|
|
271
|
-
| Option | Type | Default | Description |
|
|
272
|
-
|--------|------|---------|-------------|
|
|
273
|
-
| `maxLineWidth` | `number` | `0` | Maximum line width before wrapping (0 = no wrapping) |
|
|
274
|
-
| `alignPredicates` | `boolean` | `false` | Align predicates in columns |
|
|
275
|
-
| `alignObjects` | `boolean` | `false` | Align objects in columns (requires `alignPredicates`) |
|
|
276
|
-
| `blankNodeStyle` | `'labeled' \| 'inline' \| 'auto'` | `'auto'` | How to format blank nodes |
|
|
277
|
-
| `objectListStyle` | `'single-line' \| 'multi-line' \| 'auto'` | `'auto'` | How to format multiple objects |
|
|
278
|
-
| `predicateListStyle` | `'single-line' \| 'multi-line' \| 'first-same-line'` | `'first-same-line'` | How to format predicate lists |
|
|
279
|
-
| `blankLinesBetweenSubjects` | `boolean` | `true` | Insert blank lines between subject blocks |
|
|
280
|
-
|
|
281
|
-
#### Blank Node Style
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
// 'labeled' - Always use labeled blank nodes
|
|
285
|
-
_:b0 ex:name "Alice" .
|
|
286
|
-
_:b0 ex:knows _:b1 .
|
|
287
|
-
|
|
288
|
-
// 'inline' - Use inline property lists where possible
|
|
289
|
-
[ ex:name "Alice" ; ex:knows [ ex:name "Bob" ] ] .
|
|
290
|
-
|
|
291
|
-
// 'auto' - Inline for single-reference blank nodes, labeled for multi-reference
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
#### Object List Style
|
|
295
|
-
|
|
296
|
-
```typescript
|
|
297
|
-
// 'single-line' - Objects on same line
|
|
298
|
-
ex:s ex:p "a", "b", "c" .
|
|
299
|
-
|
|
300
|
-
// 'multi-line' - Each object on its own line
|
|
301
|
-
ex:s ex:p "a",
|
|
302
|
-
"b",
|
|
303
|
-
"c" .
|
|
304
|
-
|
|
305
|
-
// 'auto' - Based on maxLineWidth
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
#### Predicate List Style
|
|
309
|
-
|
|
310
|
-
```typescript
|
|
311
|
-
// 'first-same-line' - First predicate with subject
|
|
312
|
-
ex:s a ex:Class ;
|
|
313
|
-
ex:name "Example" ;
|
|
314
|
-
ex:value 42 .
|
|
315
|
-
|
|
316
|
-
// 'multi-line' - All predicates on separate lines
|
|
317
|
-
ex:s
|
|
318
|
-
a ex:Class ;
|
|
319
|
-
ex:name "Example" ;
|
|
320
|
-
ex:value 42 .
|
|
321
|
-
|
|
322
|
-
// 'single-line' - All on one line (compact)
|
|
323
|
-
ex:s a ex:Class ; ex:name "Example" ; ex:value 42 .
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
### JSON-LD Options
|
|
327
|
-
|
|
328
|
-
| Option | Type | Default | Description |
|
|
329
|
-
|--------|------|---------|-------------|
|
|
330
|
-
| `useTypeShorthand` | `boolean` | `true` | Use `@type` instead of `rdf:type` |
|
|
331
|
-
| `useIdShorthand` | `boolean` | `true` | Use `@id` for IRI references |
|
|
332
|
-
| `compactArrays` | `boolean` | `true` | Unwrap single-element arrays |
|
|
333
|
-
| `embedContext` | `boolean` | `true` | Include `@context` in output |
|
|
334
|
-
| `jsonIndent` | `number` | `2` | Indentation for pretty printing |
|
|
335
|
-
|
|
336
|
-
### SPARQL Options
|
|
337
|
-
|
|
338
|
-
| Option | Type | Default | Description |
|
|
339
|
-
|--------|------|---------|-------------|
|
|
340
|
-
| `uppercaseKeywords` | `boolean` | `true` | Uppercase SPARQL keywords |
|
|
341
|
-
| `lowercaseKeywords` | `boolean` | `false` | Lowercase SPARQL keywords |
|
|
342
|
-
| `alignPatterns` | `boolean` | `true` | Align WHERE clause patterns |
|
|
343
|
-
| `sameBraceLine` | `boolean` | `true` | Opening braces on same line |
|
|
344
|
-
| `separateClauses` | `boolean` | `true` | Blank lines between major clauses |
|
|
345
|
-
| `maxLineWidth` | `number` | `0` | Maximum line width before wrapping |
|
|
346
|
-
| `objectListStyle` | `string` | `'auto'` | How to format object lists in patterns |
|
|
347
|
-
| `predicateListStyle` | `string` | `'first-same-line'` | How to format predicate lists |
|
|
348
|
-
| `blankLinesBetweenSubjects` | `boolean` | `true` | Blank lines between subject blocks |
|
|
349
|
-
|
|
350
|
-
### Token Serialization Options
|
|
351
|
-
|
|
352
|
-
| Option | Type | Default | Description |
|
|
353
|
-
|--------|------|---------|-------------|
|
|
354
|
-
| `preserveBlankNodeIds` | `boolean` | `true` | Preserve original blank node IDs |
|
|
355
|
-
| `preserveComments` | `boolean` | `true` | Preserve comments from source |
|
|
356
|
-
|
|
357
|
-
## RDF 1.2 Features
|
|
358
|
-
|
|
359
|
-
### Triple Terms
|
|
360
|
-
|
|
361
|
-
```typescript
|
|
362
|
-
import { TurtleSerializer } from '@faubulous/mentor-rdf-serializers';
|
|
363
|
-
import type { TripleTerm, Rdf12Quad } from '@faubulous/mentor-rdf-serializers';
|
|
364
|
-
|
|
365
|
-
const tripleTerm: TripleTerm = {
|
|
366
|
-
termType: 'TripleTerm',
|
|
367
|
-
subject: { termType: 'NamedNode', value: 'http://example.org/s' },
|
|
368
|
-
predicate: { termType: 'NamedNode', value: 'http://example.org/p' },
|
|
369
|
-
object: { termType: 'Literal', value: 'value', language: '', datatype: { termType: 'NamedNode', value: 'http://www.w3.org/2001/XMLSchema#string' } }
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
// Output: <<( <http://example.org/s> <http://example.org/p> "value" )>>
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
### Reified Triples with Annotations
|
|
376
|
-
|
|
377
58
|
```turtle
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
# Serialized correctly with annotations
|
|
382
|
-
```
|
|
59
|
+
PREFIX ex: <http://example.org/>
|
|
60
|
+
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
|
383
61
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
```typescript
|
|
387
|
-
const literal = DataFactory.literal('مرحبا', 'ar--rtl');
|
|
388
|
-
// Output in Turtle: "مرحبا"@ar--rtl
|
|
389
|
-
// Output in JSON-LD: { "@value": "مرحبا", "@language": "ar", "@direction": "rtl" }
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
## API Reference
|
|
393
|
-
|
|
394
|
-
### Interfaces
|
|
395
|
-
|
|
396
|
-
#### `ISerializer`
|
|
397
|
-
|
|
398
|
-
```typescript
|
|
399
|
-
interface ISerializer {
|
|
400
|
-
serializeQuad(quad: Quad | Rdf12Quad, options?: SerializerOptions): string;
|
|
401
|
-
serialize(quads: Iterable<Quad | Rdf12Quad>, options?: SerializerOptions): string;
|
|
402
|
-
format(quads: Iterable<Quad | Rdf12Quad>, options?: SerializerOptions): SerializationResult;
|
|
403
|
-
}
|
|
62
|
+
ex:subject a ex:Class ;
|
|
63
|
+
ex:name "Example"@en .
|
|
404
64
|
```
|
|
405
65
|
|
|
406
|
-
|
|
66
|
+
## Documentation
|
|
407
67
|
|
|
408
|
-
|
|
409
|
-
interface SerializationResult {
|
|
410
|
-
output: string;
|
|
411
|
-
warnings?: string[];
|
|
412
|
-
sourceMap?: SourceMapEntry[];
|
|
413
|
-
}
|
|
414
|
-
```
|
|
68
|
+
Detailed guides and API documentation are available in the [docs](docs/README.md) folder:
|
|
415
69
|
|
|
416
|
-
|
|
70
|
+
| Guide | Description |
|
|
71
|
+
|-------|-------------|
|
|
72
|
+
| [Getting Started](docs/getting-started.md) | Installation and first serialization |
|
|
73
|
+
| [Architecture](docs/architecture.md) | Parser/serializer pipeline overview |
|
|
74
|
+
| [Serializers](docs/serializers.md) | Format-specific serializer usage |
|
|
75
|
+
| [Token Serialization](docs/token-serialization.md) | Serialize from parser tokens |
|
|
76
|
+
| [SPARQL Formatting](docs/sparql-formatting.md) | Query and update formatting |
|
|
77
|
+
| [Sorting](docs/sorting.md) | Quad ordering strategies |
|
|
78
|
+
| [Options](docs/options.md) | Full configuration reference |
|
|
79
|
+
| [RDF 1.2](docs/rdf-1.2.md) | Triple terms, annotations, language direction |
|
|
80
|
+
| [API Reference](docs/api-reference.md) | Interfaces and types |
|
|
81
|
+
| [VS Code Formatter](docs/vs-code-formatter.md) | Editor integration example |
|
|
417
82
|
|
|
418
|
-
|
|
419
|
-
interface ISparqlFormatter {
|
|
420
|
-
formatFromText(query: string, options?: SerializerOptions): SerializationResult;
|
|
421
|
-
formatFromTokens(tokens: unknown[], options?: SerializerOptions): SerializationResult;
|
|
422
|
-
}
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
## VS Code Formatter
|
|
426
|
-
|
|
427
|
-
Here's how to create a document formatter for Turtle files in VS Code:
|
|
428
|
-
|
|
429
|
-
```typescript
|
|
430
|
-
import * as vscode from 'vscode';
|
|
431
|
-
import { TurtleParser } from '@faubulous/mentor-rdf-parsers';
|
|
432
|
-
import { TurtleSerializer } from '@faubulous/mentor-rdf-serializers';
|
|
433
|
-
|
|
434
|
-
export class TurtleDocumentFormatter implements vscode.DocumentFormattingEditProvider {
|
|
435
|
-
private parser = new TurtleParser();
|
|
436
|
-
private serializer = new TurtleSerializer();
|
|
437
|
-
|
|
438
|
-
provideDocumentFormattingEdits(
|
|
439
|
-
document: vscode.TextDocument,
|
|
440
|
-
options: vscode.FormattingOptions,
|
|
441
|
-
token: vscode.CancellationToken
|
|
442
|
-
): vscode.TextEdit[] {
|
|
443
|
-
const text = document.getText();
|
|
444
|
-
|
|
445
|
-
// Parse the document
|
|
446
|
-
const parseResult = this.parser.parse(text);
|
|
447
|
-
|
|
448
|
-
if (parseResult.errors.length > 0) {
|
|
449
|
-
// Don't format if there are parse errors
|
|
450
|
-
return [];
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// Get user preferences from VS Code settings
|
|
454
|
-
const config = vscode.workspace.getConfiguration('turtle');
|
|
455
|
-
|
|
456
|
-
// Serialize with formatting options
|
|
457
|
-
const result = this.serializer.serialize(parseResult.quads, {
|
|
458
|
-
prefixes: parseResult.prefixes,
|
|
459
|
-
baseIri: parseResult.baseIri,
|
|
460
|
-
indent: options.insertSpaces ? ' '.repeat(options.tabSize) : '\t',
|
|
461
|
-
prettyPrint: true,
|
|
462
|
-
groupBySubject: true,
|
|
463
|
-
sort: config.get('sortStatements', true),
|
|
464
|
-
maxLineWidth: config.get('maxLineWidth', 80),
|
|
465
|
-
alignPredicates: config.get('alignPredicates', false),
|
|
466
|
-
blankNodeStyle: config.get('blankNodeStyle', 'auto'),
|
|
467
|
-
predicateListStyle: config.get('predicateListStyle', 'first-same-line'),
|
|
468
|
-
blankLinesBetweenSubjects: config.get('blankLinesBetweenSubjects', true)
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
// Return a single edit replacing the entire document
|
|
472
|
-
const fullRange = new vscode.Range(
|
|
473
|
-
document.positionAt(0),
|
|
474
|
-
document.positionAt(text.length)
|
|
475
|
-
);
|
|
476
|
-
|
|
477
|
-
return [vscode.TextEdit.replace(fullRange, result.output)];
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
// Register the formatter in your extension's activate function
|
|
482
|
-
export function activate(context: vscode.ExtensionContext) {
|
|
483
|
-
context.subscriptions.push(
|
|
484
|
-
vscode.languages.registerDocumentFormattingEditProvider(
|
|
485
|
-
{ language: 'turtle', scheme: 'file' },
|
|
486
|
-
new TurtleDocumentFormatter()
|
|
487
|
-
)
|
|
488
|
-
);
|
|
489
|
-
}
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
### SPARQL Formatter for VS Code
|
|
493
|
-
|
|
494
|
-
```typescript
|
|
495
|
-
import * as vscode from 'vscode';
|
|
496
|
-
import { SparqlFormatter } from '@faubulous/mentor-rdf-serializers';
|
|
497
|
-
|
|
498
|
-
export class SparqlDocumentFormatter implements vscode.DocumentFormattingEditProvider {
|
|
499
|
-
private formatter = new SparqlFormatter();
|
|
500
|
-
|
|
501
|
-
provideDocumentFormattingEdits(
|
|
502
|
-
document: vscode.TextDocument,
|
|
503
|
-
options: vscode.FormattingOptions,
|
|
504
|
-
token: vscode.CancellationToken
|
|
505
|
-
): vscode.TextEdit[] {
|
|
506
|
-
const text = document.getText();
|
|
507
|
-
const config = vscode.workspace.getConfiguration('sparql');
|
|
508
|
-
|
|
509
|
-
const result = this.formatter.formatFromText(text, {
|
|
510
|
-
indent: options.insertSpaces ? ' '.repeat(options.tabSize) : '\t',
|
|
511
|
-
prettyPrint: true,
|
|
512
|
-
uppercaseKeywords: config.get('uppercaseKeywords', true),
|
|
513
|
-
alignPatterns: config.get('alignPatterns', true),
|
|
514
|
-
sameBraceLine: config.get('sameBraceLine', true),
|
|
515
|
-
separateClauses: config.get('separateClauses', true),
|
|
516
|
-
maxLineWidth: config.get('maxLineWidth', 80)
|
|
517
|
-
});
|
|
518
|
-
|
|
519
|
-
const fullRange = new vscode.Range(
|
|
520
|
-
document.positionAt(0),
|
|
521
|
-
document.positionAt(text.length)
|
|
522
|
-
);
|
|
523
|
-
|
|
524
|
-
return [vscode.TextEdit.replace(fullRange, result.output)];
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
### Range Formatting (Format Selection)
|
|
530
|
-
|
|
531
|
-
For formatting only a selected range, use the `TokenSerializer` to preserve surrounding content:
|
|
532
|
-
|
|
533
|
-
```typescript
|
|
534
|
-
import { TurtleParser } from '@faubulous/mentor-rdf-parsers';
|
|
535
|
-
import { TokenSerializer } from '@faubulous/mentor-rdf-serializers';
|
|
536
|
-
|
|
537
|
-
export class TurtleRangeFormatter implements vscode.DocumentRangeFormattingEditProvider {
|
|
538
|
-
private parser = new TurtleParser();
|
|
539
|
-
private tokenSerializer = new TokenSerializer();
|
|
540
|
-
|
|
541
|
-
provideDocumentRangeFormattingEdits(
|
|
542
|
-
document: vscode.TextDocument,
|
|
543
|
-
range: vscode.Range,
|
|
544
|
-
options: vscode.FormattingOptions,
|
|
545
|
-
token: vscode.CancellationToken
|
|
546
|
-
): vscode.TextEdit[] {
|
|
547
|
-
const text = document.getText();
|
|
548
|
-
const parseResult = this.parser.parse(text);
|
|
549
|
-
|
|
550
|
-
if (parseResult.errors.length > 0) {
|
|
551
|
-
return [];
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
// Get byte offsets for the selected range
|
|
555
|
-
const startOffset = document.offsetAt(range.start);
|
|
556
|
-
const endOffset = document.offsetAt(range.end);
|
|
557
|
-
|
|
558
|
-
// Serialize only tokens within the range
|
|
559
|
-
const result = this.tokenSerializer.serializeRange(
|
|
560
|
-
parseResult.tokens,
|
|
561
|
-
startOffset,
|
|
562
|
-
endOffset,
|
|
563
|
-
{ preserveComments: true, preserveBlankNodeIds: true }
|
|
564
|
-
);
|
|
565
|
-
|
|
566
|
-
return [vscode.TextEdit.replace(range, result.output)];
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
```
|
|
570
|
-
|
|
571
|
-
## License
|
|
83
|
+
## Related Projects
|
|
572
84
|
|
|
573
|
-
|
|
85
|
+
| Package | Description |
|
|
86
|
+
|---------|-------------|
|
|
87
|
+
| [@faubulous/mentor-rdf-parsers](https://github.com/faubulous/mentor-rdf-parsers) | RDF parsing library — the parser counterpart |
|
|
88
|
+
| [@faubulous/mentor-vscode](https://github.com/faubulous/mentor-vscode) | RDF IDE and workbench for VS Code |
|
|
574
89
|
|
|
575
90
|
## Contributing
|
|
576
91
|
|
|
577
|
-
Contributions are welcome
|
|
92
|
+
Contributions are welcome. Please feel free to open an issue or submit a pull request on [GitHub](https://github.com/faubulous/mentor-rdf-serializers).
|
|
578
93
|
|
|
579
|
-
##
|
|
94
|
+
## License
|
|
580
95
|
|
|
581
|
-
|
|
582
|
-
- [@faubulous/mentor-vscode](https://github.com/faubulous/mentor-vscode) - RDF IDE and workbench
|
|
96
|
+
[LGPL-2.1-or-later](https://github.com/faubulous/mentor-rdf-serializers/blob/main/LICENSE)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
export { RdfSyntax } from './types.js';
|
|
1
|
+
export type { BlankNodeStyle, IRdfFormatter, ISerializer, ISparqlFormatter, ITokenSerializer, ObjectListStyle, PredicateListStyle, PriorityStrategyConfig, QuadComparator, Rdf12Quad, Rdf12Term, RdfSyntax, Reifier, SerializationResult, SerializerOptions, SortingStrategy, SortOption, SourceMapEntry, TokenSerializerOptions, TripleTerm, } from './types.js';
|
|
3
2
|
export { escapeIri, escapeString, escapeLocalName, findPrefix, isValidLocalName, isTripleTerm, isReifier, hasAnnotations, hasReifier, needsLongString, isInteger, isDecimal, isDouble, groupQuadsBySubject, groupQuadsBySubjectPredicate, groupQuadsByGraph, termToString, sortQuads, parseLanguageTag, formatLanguageTag, resetBlankNodeCounter, generateBlankNodeId, mergeOptions, RDF_NAMESPACE, XSD_NAMESPACE, RDF_TYPE, XSD_STRING, XSD_INTEGER, XSD_DECIMAL, XSD_DOUBLE, XSD_BOOLEAN, DEFAULT_OPTIONS } from './utils.js';
|
|
4
3
|
export { BaseSerializer } from './base-serializer.js';
|
|
5
4
|
export { BaseTokenFormatter, annotateTokens, type TokenAnnotation, type AnnotatedToken, type Scope, type BaseFormatterContext, type BaseFormatterOptions, } from './base-token-formatter.js';
|
|
@@ -17,4 +16,6 @@ export { TrigFormatter, type TrigFormatterOptions } from './trig/formatter.js';
|
|
|
17
16
|
export { N3Formatter, type N3FormatterOptions } from './n3/formatter.js';
|
|
18
17
|
export { TokenSerializer, type Token, getBlankNodeIdFromToken, isBlankNodeToken, getTokenPosition } from './token-serializer.js';
|
|
19
18
|
export { alphabeticalStrategy, createByTypeStrategy, createSemanticStrategy, createPriorityStrategy, applySortingStrategy } from './sorting/index.js';
|
|
19
|
+
export { StatementSerializer } from './statement-serializer.js';
|
|
20
|
+
export type { StatementSerializerOptions, QuadTokens, QuadContext } from './statement-serializer.js';
|
|
20
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACR,cAAc,EACd,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,cAAc,EACd,SAAS,EACT,SAAS,EACT,SAAS,EACT,OAAO,EACP,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,UAAU,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EACH,SAAS,EACT,YAAY,EACZ,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,cAAc,EACd,UAAU,EACV,eAAe,EACf,SAAS,EACT,SAAS,EACT,QAAQ,EACR,mBAAmB,EACnB,4BAA4B,EAC5B,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,QAAQ,EACR,UAAU,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,WAAW,EACX,eAAe,EAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EACH,kBAAkB,EAClB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,KAAK,EACV,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC5B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EACH,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,WAAW,EACX,iBAAiB,EACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EACH,eAAe,EACf,KAAK,KAAK,EACV,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACH,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACvB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EACR,0BAA0B,EAC1B,UAAU,EACV,WAAW,EACd,MAAM,2BAA2B,CAAC"}
|