mdld-parse 0.2.2 → 0.2.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/LICENCE +167 -0
- package/README.md +341 -190
- package/index.js +722 -284
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,300 +1,451 @@
|
|
|
1
|
-
# MD-LD Parse
|
|
1
|
+
# MD-LD Parse v0.2
|
|
2
2
|
|
|
3
|
-
**Markdown-Linked Data (MD-LD)** — a
|
|
3
|
+
**Markdown-Linked Data (MD-LD)** — a deterministic, streaming-friendly RDF authoring format that extends Markdown with explicit `{}` annotations.
|
|
4
4
|
|
|
5
|
-
[NPM](https://www.npmjs.com/package/mdld-parse)
|
|
5
|
+
[](https://www.npmjs.com/package/mdld-parse)
|
|
6
|
+
[](https://github.com/mdld-js/mdld-parse)
|
|
6
7
|
|
|
7
|
-
[
|
|
8
|
+
[Documentation](https://mdld.js.org) | [Specification](https://mdld.js.org/spec) | [Playground](https://mdld.js.org/playground)
|
|
8
9
|
|
|
9
10
|
## What is MD-LD?
|
|
10
11
|
|
|
11
|
-
MD-LD allows you to author RDF graphs directly in Markdown using
|
|
12
|
+
MD-LD allows you to author RDF graphs directly in Markdown using explicit `{}` annotations:
|
|
12
13
|
|
|
13
14
|
```markdown
|
|
14
|
-
#
|
|
15
|
+
# Apollo 11 {=ex:apollo11 .SpaceMission}
|
|
15
16
|
|
|
16
|
-
[
|
|
17
|
+
Launch: [1969-07-16] {startDate ^^xsd:date}
|
|
18
|
+
Crew: [Neil Armstrong](ex:armstrong) {?crewMember}
|
|
19
|
+
Description: [First crewed Moon landing] {description}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Generates valid RDF triples:
|
|
23
|
+
|
|
24
|
+
```turtle
|
|
25
|
+
ex:apollo11 a schema:SpaceMission ;
|
|
26
|
+
schema:startDate "1969-07-16"^^xsd:date ;
|
|
27
|
+
schema:crewMember ex:armstrong ;
|
|
28
|
+
schema:description "First crewed Moon landing" .
|
|
29
|
+
```
|
|
17
30
|
|
|
18
|
-
|
|
31
|
+
## Core Guarantees
|
|
19
32
|
|
|
20
|
-
|
|
33
|
+
MD-LD v0.2 provides strict semantic guarantees:
|
|
21
34
|
|
|
22
|
-
|
|
35
|
+
1. **CommonMark-preserving** — Removing `{}` yields valid Markdown
|
|
36
|
+
2. **Explicit semantics** — Every quad originates from explicit `{}`
|
|
37
|
+
3. **Single-pass parsing** — Streaming-friendly, deterministic
|
|
38
|
+
4. **No blank nodes** — All subjects are stable IRIs
|
|
39
|
+
5. **Complete traceability** — Every quad maps to source location
|
|
40
|
+
6. **Round-trip capable** — Markdown ↔ RDF ↔ Markdown preserves structure
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install mdld-parse
|
|
23
46
|
```
|
|
24
47
|
|
|
25
|
-
|
|
48
|
+
### Node.js
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
import { parse } from 'mdld-parse';
|
|
52
|
+
|
|
53
|
+
const markdown = `# Document {=ex:doc .Article}
|
|
54
|
+
|
|
55
|
+
[Alice] {author}`;
|
|
56
|
+
|
|
57
|
+
const result = parse(markdown, {
|
|
58
|
+
context: { ex: 'http://example.org/' }
|
|
59
|
+
});
|
|
26
60
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<urn:mdld:my-note-20251231> <http://schema.org/author> <http://example.org/alice> .
|
|
30
|
-
<http://example.org/alice> <http://schema.org/name> "Alice" .
|
|
31
|
-
<http://example.org/alice> <http://schema.org/worksFor> <http://example.org/tech-corp> .
|
|
61
|
+
console.log(result.quads);
|
|
62
|
+
// RDF/JS quads ready for n3.js, rdflib, etc.
|
|
32
63
|
```
|
|
33
64
|
|
|
34
|
-
|
|
65
|
+
### Browser (ES Modules)
|
|
35
66
|
|
|
36
|
-
|
|
67
|
+
```html
|
|
68
|
+
<script type="module">
|
|
69
|
+
import { parse } from 'https://cdn.jsdelivr.net/npm/mdld-parse/+esm';
|
|
70
|
+
|
|
71
|
+
const result = parse('# Hello {=ex:hello}');
|
|
72
|
+
</script>
|
|
73
|
+
```
|
|
37
74
|
|
|
38
|
-
|
|
39
|
-
2. **Zero Dependencies** — Pure JavaScript, runs in Node.js and browsers
|
|
40
|
-
3. **Standards Compliant** — Outputs RDF quads compatible with RDFa semantics
|
|
41
|
-
4. **Markdown Native** — Plain Markdown yields minimal but valid RDF
|
|
42
|
-
5. **Progressive Enhancement** — Add semantics incrementally via attributes
|
|
43
|
-
6. **BaseIRI Inference** — Automatically infers baseIRI from document structure
|
|
44
|
-
7. **Default Vocabulary** — Provides default vocabulary for common properties, extensible via options
|
|
75
|
+
## Semantic Model
|
|
45
76
|
|
|
46
|
-
|
|
77
|
+
MD-LD encodes a directed labeled multigraph where three nodes may be in scope:
|
|
47
78
|
|
|
48
|
-
|
|
79
|
+
- **S** — current subject (IRI)
|
|
80
|
+
- **O** — object resource (IRI from link/image)
|
|
81
|
+
- **L** — literal value (string + optional datatype/language)
|
|
49
82
|
|
|
50
|
-
|
|
83
|
+
### Predicate Routing (§8.1)
|
|
51
84
|
|
|
52
|
-
|
|
53
|
-
- **Inline attribute parser** — Pandoc-style `{=iri .class key="value"}` attribute extraction
|
|
54
|
-
- **RDF quad generator** — Direct mapping from tokens to RDF/JS quads
|
|
85
|
+
Each predicate form determines the graph edge:
|
|
55
86
|
|
|
56
|
-
|
|
87
|
+
| Form | Edge | Example | Meaning |
|
|
88
|
+
|-------|---------|------------------------------|------------------|
|
|
89
|
+
| `p` | S → L | `[Alice] {name}` | literal property |
|
|
90
|
+
| `?p` | S → O | `[NASA](ex:nasa) {?org}` | object property |
|
|
91
|
+
| `^p` | *(none)*| *(literals can't be subjects)* | reverse literal |
|
|
92
|
+
| `^?p` | O → S | `[Parent](ex:p) {^?hasPart}` | reverse object |
|
|
57
93
|
|
|
58
|
-
|
|
59
|
-
- **Lightweight** — ~15KB minified, no AST overhead
|
|
60
|
-
- **Focused** — Optimized specifically for MD-LD semantics
|
|
61
|
-
- **Transparent** — Easy to understand and extend
|
|
62
|
-
- **Fast** — Single-pass parsing with minimal allocations
|
|
94
|
+
## Syntax Reference
|
|
63
95
|
|
|
64
|
-
|
|
96
|
+
### Subject Declaration
|
|
65
97
|
|
|
66
|
-
|
|
98
|
+
Set the current subject (emits no quads):
|
|
67
99
|
|
|
68
|
-
```
|
|
69
|
-
{
|
|
70
|
-
termType: 'NamedNode' | 'BlankNode' | 'Literal',
|
|
71
|
-
value: string,
|
|
72
|
-
language?: string,
|
|
73
|
-
datatype?: NamedNode
|
|
74
|
-
}
|
|
100
|
+
```markdown
|
|
101
|
+
## Apollo 11 {=ex:apollo11}
|
|
75
102
|
```
|
|
76
103
|
|
|
77
|
-
|
|
104
|
+
Subject remains in scope until reset with `{=}` or new subject declared.
|
|
78
105
|
|
|
79
|
-
|
|
80
|
-
- `rdflib.js` — RDF store and reasoning
|
|
81
|
-
- `sparqljs` — SPARQL query parsing
|
|
82
|
-
- `rdf-ext` — Extended RDF utilities
|
|
106
|
+
### Type Declaration
|
|
83
107
|
|
|
84
|
-
|
|
108
|
+
Emit `rdf:type` triple:
|
|
85
109
|
|
|
110
|
+
```markdown
|
|
111
|
+
## Apollo 11 {=ex:apollo11 .SpaceMission .Event}
|
|
86
112
|
```
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
↓
|
|
91
|
-
[Attribute Parser] — Parse {=iri .class key="value"} from tokens
|
|
92
|
-
↓
|
|
93
|
-
[Inline Parser] — Extract [text](url){attrs} spans
|
|
94
|
-
↓
|
|
95
|
-
[RDF Quad Generator] — Map tokens to RDF/JS quads
|
|
96
|
-
↓
|
|
97
|
-
RDF Quads (RDF/JS format)
|
|
98
|
-
↓
|
|
99
|
-
[Optional] n3.js Writer → Turtle/N-Triples
|
|
113
|
+
|
|
114
|
+
```turtle
|
|
115
|
+
ex:apollo11 a schema:SpaceMission, schema:Event .
|
|
100
116
|
```
|
|
101
117
|
|
|
102
|
-
###
|
|
118
|
+
### Literal Properties
|
|
103
119
|
|
|
104
|
-
|
|
120
|
+
Inline value carriers emit literal properties:
|
|
105
121
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
3. **Predictable performance** — Linear time complexity, bounded memory
|
|
109
|
-
4. **Easy integration** — Works in Node.js, browsers, and edge runtimes
|
|
122
|
+
```markdown
|
|
123
|
+
# Mission {=ex:apollo11}
|
|
110
124
|
|
|
111
|
-
|
|
125
|
+
[Neil Armstrong] {commander}
|
|
126
|
+
[1969] {year ^^xsd:gYear}
|
|
127
|
+
[Historic mission] {description @en}
|
|
128
|
+
```
|
|
112
129
|
|
|
113
|
-
|
|
130
|
+
```turtle
|
|
131
|
+
ex:apollo11 schema:commander "Neil Armstrong" ;
|
|
132
|
+
schema:year "1969"^^xsd:gYear ;
|
|
133
|
+
schema:description "Historic mission"@en .
|
|
134
|
+
```
|
|
114
135
|
|
|
115
|
-
|
|
116
|
-
|
|
136
|
+
### Object Properties
|
|
137
|
+
|
|
138
|
+
Links create relationships (use `?` prefix):
|
|
139
|
+
|
|
140
|
+
```markdown
|
|
141
|
+
# Mission {=ex:apollo11}
|
|
142
|
+
|
|
143
|
+
[NASA](ex:nasa) {?organizer}
|
|
117
144
|
```
|
|
118
145
|
|
|
119
|
-
```
|
|
120
|
-
|
|
146
|
+
```turtle
|
|
147
|
+
ex:apollo11 schema:organizer ex:nasa .
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Resource Declaration
|
|
151
|
+
|
|
152
|
+
Declare resources inline with `{=iri}`:
|
|
153
|
+
|
|
154
|
+
```markdown
|
|
155
|
+
# Mission {=ex:apollo11}
|
|
121
156
|
|
|
122
|
-
|
|
123
|
-
const result = parse(markdown);
|
|
124
|
-
const quads = result.quads;
|
|
157
|
+
[Neil Armstrong] {=ex:armstrong ?commander .Person}
|
|
125
158
|
```
|
|
126
159
|
|
|
127
|
-
|
|
160
|
+
```turtle
|
|
161
|
+
ex:apollo11 schema:commander ex:armstrong .
|
|
162
|
+
ex:armstrong a schema:Person .
|
|
163
|
+
```
|
|
128
164
|
|
|
129
|
-
|
|
130
|
-
<script type="importmap">
|
|
131
|
-
{
|
|
132
|
-
"imports": {
|
|
133
|
-
"mdld-parse": "https://cdn.jsdelivr.net/npm/mdld-parse/+esm"
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
</script>
|
|
165
|
+
### Lists
|
|
137
166
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
167
|
+
Lists require explicit subjects per item:
|
|
168
|
+
|
|
169
|
+
```markdown
|
|
170
|
+
# Recipe {=ex:recipe}
|
|
171
|
+
|
|
172
|
+
Ingredients: {?ingredient .Ingredient}
|
|
173
|
+
|
|
174
|
+
- Flour {=ex:flour name}
|
|
175
|
+
- Water {=ex:water name}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```turtle
|
|
179
|
+
ex:recipe schema:ingredient ex:flour, ex:water .
|
|
180
|
+
ex:flour a schema:Ingredient ; schema:name "Flour" .
|
|
181
|
+
ex:water a schema:Ingredient ; schema:name "Water" .
|
|
142
182
|
```
|
|
143
183
|
|
|
144
|
-
|
|
184
|
+
### Code Blocks
|
|
185
|
+
|
|
186
|
+
Code blocks are value carriers:
|
|
187
|
+
|
|
188
|
+
````markdown
|
|
189
|
+
# Example {=ex:example}
|
|
190
|
+
|
|
191
|
+
```javascript {=ex:code .SoftwareSourceCode text}
|
|
192
|
+
console.log("hello");
|
|
193
|
+
```
|
|
194
|
+
````
|
|
195
|
+
|
|
196
|
+
```turtle
|
|
197
|
+
ex:code a schema:SoftwareSourceCode ;
|
|
198
|
+
schema:text "console.log(\"hello\")" .
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Blockquotes
|
|
202
|
+
|
|
203
|
+
```markdown
|
|
204
|
+
# Article {=ex:article}
|
|
205
|
+
|
|
206
|
+
> MD-LD bridges Markdown and RDF. {abstract}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
```turtle
|
|
210
|
+
ex:article schema:abstract "MD-LD bridges Markdown and RDF." .
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Reverse Relations
|
|
214
|
+
|
|
215
|
+
Reverse the relationship direction:
|
|
216
|
+
|
|
217
|
+
```markdown
|
|
218
|
+
# Part {=ex:part}
|
|
219
|
+
|
|
220
|
+
Part of: {^?hasPart}
|
|
221
|
+
|
|
222
|
+
- Book {=ex:book}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
```turtle
|
|
226
|
+
ex:book schema:hasPart ex:part .
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Prefix Declarations
|
|
230
|
+
|
|
231
|
+
```markdown
|
|
232
|
+
[ex] {: http://example.org/}
|
|
233
|
+
[foaf] {: http://xmlns.com/foaf/0.1/}
|
|
234
|
+
|
|
235
|
+
# Person {=ex:alice .foaf:Person}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## API Reference
|
|
145
239
|
|
|
146
240
|
### `parse(markdown, options)`
|
|
147
241
|
|
|
148
|
-
Parse MD-LD markdown and return
|
|
242
|
+
Parse MD-LD markdown and return RDF quads with origin tracking.
|
|
149
243
|
|
|
150
244
|
**Parameters:**
|
|
151
245
|
|
|
152
246
|
- `markdown` (string) — MD-LD formatted text
|
|
153
247
|
- `options` (object, optional):
|
|
154
|
-
- `
|
|
155
|
-
- `
|
|
156
|
-
|
|
248
|
+
- `context` (object) — Prefix mappings (default: `{ '@vocab': 'http://schema.org/', rdf, rdfs, xsd, schema }`)
|
|
249
|
+
- `dataFactory` (object) — Custom RDF/JS DataFactory
|
|
250
|
+
|
|
251
|
+
**Returns:** `{ quads, origin, context }`
|
|
157
252
|
|
|
158
|
-
**Returns:** Object containing:
|
|
159
253
|
- `quads` — Array of RDF/JS Quads
|
|
160
|
-
- `origin` —
|
|
161
|
-
- `
|
|
254
|
+
- `origin` — Origin tracking object with:
|
|
255
|
+
- `blocks` — Map of block IDs to source locations
|
|
256
|
+
- `quadIndex` — Map of quads to block IDs
|
|
257
|
+
- `context` — Final context used (includes prefixes)
|
|
258
|
+
|
|
259
|
+
**Example:**
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
const result = parse(
|
|
263
|
+
`# Article {=ex:article .Article}
|
|
264
|
+
|
|
265
|
+
[Alice](ex:alice) {?author}`,
|
|
266
|
+
{ context: { ex: 'http://example.org/' } }
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
console.log(result.quads);
|
|
270
|
+
// [
|
|
271
|
+
// {
|
|
272
|
+
// subject: { termType: 'NamedNode', value: 'http://example.org/article' },
|
|
273
|
+
// predicate: { termType: 'NamedNode', value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' },
|
|
274
|
+
// object: { termType: 'NamedNode', value: 'http://schema.org/Article' }
|
|
275
|
+
// },
|
|
276
|
+
// ...
|
|
277
|
+
// ]
|
|
278
|
+
```
|
|
162
279
|
|
|
163
280
|
### `serialize({ text, diff, origin, options })`
|
|
164
281
|
|
|
165
|
-
|
|
282
|
+
Apply RDF changes back to markdown with proper positioning.
|
|
166
283
|
|
|
167
284
|
**Parameters:**
|
|
168
285
|
|
|
169
|
-
- `text` (string) — Original markdown
|
|
286
|
+
- `text` (string) — Original markdown
|
|
170
287
|
- `diff` (object) — Changes to apply:
|
|
171
|
-
- `add` —
|
|
172
|
-
- `delete` —
|
|
173
|
-
- `origin` (object) — Origin
|
|
174
|
-
- `options` (object, optional)
|
|
175
|
-
- `context` (object) — Context for IRI shortening
|
|
288
|
+
- `add` (array) — Quads to add
|
|
289
|
+
- `delete` (array) — Quads to remove
|
|
290
|
+
- `origin` (object) — Origin from `parse()` result
|
|
291
|
+
- `options` (object, optional):
|
|
292
|
+
- `context` (object) — Context for IRI shortening
|
|
293
|
+
|
|
294
|
+
**Returns:** `{ text, origin }`
|
|
176
295
|
|
|
177
|
-
|
|
178
|
-
- `
|
|
179
|
-
|
|
296
|
+
- `text` — Updated markdown
|
|
297
|
+
- `origin` — Updated origin tracking
|
|
298
|
+
|
|
299
|
+
**Example:**
|
|
180
300
|
|
|
181
301
|
```javascript
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
Written by [Alice](ex:alice) {ex:author}
|
|
187
|
-
`,
|
|
188
|
-
{
|
|
189
|
-
baseIRI: "http://example.org/doc",
|
|
190
|
-
context: {
|
|
191
|
-
'@vocab': 'http://schema.org/',
|
|
192
|
-
},
|
|
193
|
-
}
|
|
194
|
-
);
|
|
302
|
+
const original = `# Article {=ex:article}
|
|
303
|
+
|
|
304
|
+
[Alice] {author}`;
|
|
195
305
|
|
|
196
|
-
|
|
197
|
-
// subject: { termType: 'NamedNode', value: 'http://example.org/doc#article' },
|
|
198
|
-
// predicate: { termType: 'NamedNode', value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' },
|
|
199
|
-
// object: { termType: 'NamedNode', value: 'http://schema.org/Article' },
|
|
200
|
-
// graph: { termType: 'DefaultGraph' }
|
|
201
|
-
// }
|
|
306
|
+
const result = parse(original, { context: { ex: 'http://example.org/' } });
|
|
202
307
|
|
|
203
|
-
// Add a new
|
|
308
|
+
// Add a new property
|
|
204
309
|
const newQuad = {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
310
|
+
subject: { termType: 'NamedNode', value: 'http://example.org/article' },
|
|
311
|
+
predicate: { termType: 'NamedNode', value: 'http://schema.org/datePublished' },
|
|
312
|
+
object: { termType: 'Literal', value: '2024-01-01' }
|
|
208
313
|
};
|
|
209
314
|
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
315
|
+
const updated = serialize({
|
|
316
|
+
text: original,
|
|
317
|
+
diff: { add: [newQuad] },
|
|
318
|
+
origin: result.origin,
|
|
319
|
+
options: { context: result.context }
|
|
215
320
|
});
|
|
216
321
|
|
|
217
|
-
|
|
322
|
+
console.log(updated.text);
|
|
323
|
+
// # Article {=ex:article}
|
|
324
|
+
//
|
|
325
|
+
// [Alice] {author}
|
|
326
|
+
// [2024-01-01] {datePublished}
|
|
218
327
|
```
|
|
219
328
|
|
|
220
|
-
##
|
|
329
|
+
## Value Carriers
|
|
221
330
|
|
|
222
|
-
|
|
331
|
+
Only specific markdown elements can carry semantic values:
|
|
223
332
|
|
|
224
|
-
|
|
333
|
+
**Inline:**
|
|
334
|
+
- `[text] {...}` — span with annotation
|
|
335
|
+
- `[text](url) {...}` — link to external resource
|
|
336
|
+
- `[text] {...}` — inline resource declaration
|
|
337
|
+
- ` {...}` — embedding with annotation
|
|
225
338
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
339
|
+
**Block:**
|
|
340
|
+
- Headings (`# Title`)
|
|
341
|
+
- List items (`- item`, `1. item`) (single-level)
|
|
342
|
+
- Blockquotes (`> quote`)
|
|
343
|
+
- Code blocks (` ```lang `)
|
|
230
344
|
|
|
231
|
-
|
|
232
|
-
# Document {=urn:mdld:doc .Article}
|
|
345
|
+
## Architecture
|
|
233
346
|
|
|
234
|
-
|
|
347
|
+
### Design Principles
|
|
235
348
|
|
|
236
|
-
|
|
349
|
+
- **Zero dependencies** — Pure JavaScript, ~15KB minified
|
|
350
|
+
- **Streaming-first** — Single-pass parsing, O(n) complexity
|
|
351
|
+
- **Standards-compliant** — RDF/JS data model
|
|
352
|
+
- **Origin tracking** — Full round-trip support with source maps
|
|
353
|
+
- **Explicit semantics** — No guessing, inference, or heuristics
|
|
237
354
|
|
|
238
|
-
|
|
239
|
-
```
|
|
355
|
+
### RDF/JS Compatibility
|
|
240
356
|
|
|
241
|
-
|
|
357
|
+
Quads are compatible with:
|
|
242
358
|
|
|
243
|
-
|
|
244
|
-
-
|
|
245
|
-
-
|
|
246
|
-
|
|
359
|
+
- [`n3.js`](https://github.com/rdfjs/N3.js) — Turtle/N-Triples serialization
|
|
360
|
+
- [`rdflib.js`](https://github.com/linkeddata/rdflib.js) — RDF store and reasoning
|
|
361
|
+
- [`sparqljs`](https://github.com/RubenVerborgh/SPARQL.js) — SPARQL queries
|
|
362
|
+
- [`rdf-ext`](https://github.com/rdf-ext/rdf-ext) — Extended RDF utilities
|
|
247
363
|
|
|
248
|
-
|
|
364
|
+
## Forbidden Constructs
|
|
249
365
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
366
|
+
MD-LD explicitly forbids to ensure deterministic parsing:
|
|
367
|
+
|
|
368
|
+
- ❌ Implicit semantics or structural inference
|
|
369
|
+
- ❌ Auto-generated subjects or blank nodes
|
|
370
|
+
- ❌ Predicate guessing from context
|
|
371
|
+
- ❌ Multi-pass or backtracking parsers
|
|
254
372
|
|
|
255
|
-
|
|
373
|
+
## Use Cases
|
|
374
|
+
|
|
375
|
+
### Personal Knowledge Management
|
|
256
376
|
|
|
257
377
|
```markdown
|
|
258
|
-
|
|
259
|
-
SELECT \* WHERE { ?s ?p ?o }
|
|
260
|
-
\`\`\`
|
|
261
|
-
```
|
|
378
|
+
# Meeting Notes {=urn:note:2024-01-15 .Meeting}
|
|
262
379
|
|
|
263
|
-
|
|
380
|
+
Attendees: {?attendee}
|
|
264
381
|
|
|
265
|
-
-
|
|
266
|
-
-
|
|
267
|
-
- `schema:text` with the raw source code
|
|
268
|
-
- `schema:hasPart` link from the surrounding section
|
|
382
|
+
- Alice {=urn:person:alice name}
|
|
383
|
+
- Bob {=urn:person:bob name}
|
|
269
384
|
|
|
270
|
-
|
|
385
|
+
Action items: {?actionItem}
|
|
271
386
|
|
|
272
|
-
|
|
387
|
+
- Review proposal {=urn:task:1 name}
|
|
388
|
+
```
|
|
273
389
|
|
|
274
|
-
###
|
|
390
|
+
### Developer Documentation
|
|
275
391
|
|
|
276
|
-
|
|
392
|
+
````markdown
|
|
393
|
+
# API Endpoint {=api:/users/:id .APIEndpoint}
|
|
277
394
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
```
|
|
395
|
+
[GET] {method}
|
|
396
|
+
[/users/:id] {path}
|
|
281
397
|
|
|
282
|
-
|
|
398
|
+
Example:
|
|
283
399
|
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
[30] {age ^^xsd:integer}
|
|
400
|
+
```bash {=api:/users/:id#example .CodeExample text}
|
|
401
|
+
curl https://api.example.com/users/123
|
|
287
402
|
```
|
|
403
|
+
````
|
|
288
404
|
|
|
289
|
-
|
|
405
|
+
### Academic Research
|
|
290
406
|
|
|
291
407
|
```markdown
|
|
292
|
-
|
|
408
|
+
# Paper {=doi:10.1234/example .ScholarlyArticle}
|
|
409
|
+
|
|
410
|
+
[Semantic Web] {about}
|
|
411
|
+
[Alice Johnson] {=orcid:0000-0001-2345-6789 author}
|
|
412
|
+
[2024-01] {datePublished ^^xsd:gYearMonth}
|
|
413
|
+
|
|
414
|
+
> This paper explores semantic markup in Markdown. {abstract @en}
|
|
293
415
|
```
|
|
294
416
|
|
|
295
|
-
|
|
417
|
+
## Testing
|
|
296
418
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
419
|
+
The parser includes comprehensive tests covering all spec requirements:
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
npm test
|
|
300
423
|
```
|
|
424
|
+
|
|
425
|
+
Tests validate:
|
|
426
|
+
- Subject declaration and context
|
|
427
|
+
- All predicate forms (p, ?p, ^p, ^?p)
|
|
428
|
+
- Datatypes and language tags
|
|
429
|
+
- List processing
|
|
430
|
+
- Code blocks and blockquotes
|
|
431
|
+
- Round-trip serialization
|
|
432
|
+
|
|
433
|
+
## Contributing
|
|
434
|
+
|
|
435
|
+
Contributions welcome! Please:
|
|
436
|
+
|
|
437
|
+
1. Read the [specification](https://mdld.js.org/spec)
|
|
438
|
+
2. Add tests for new features
|
|
439
|
+
3. Ensure all tests pass
|
|
440
|
+
4. Follow existing code style
|
|
441
|
+
|
|
442
|
+
## Acknowledgments
|
|
443
|
+
|
|
444
|
+
Inspired by:
|
|
445
|
+
- Thomas Francart's [Semantic Markdown](https://blog.sparna.fr/2020/02/20/semantic-markdown/)
|
|
446
|
+
- RDFa decades of structured data experience
|
|
447
|
+
- CommonMark's rigorous parsing approach
|
|
448
|
+
|
|
449
|
+
## License
|
|
450
|
+
|
|
451
|
+
See [LICENCE](./LICENCE)
|