Skip to content

Commit

Permalink
feat: parsing rules
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Nov 29, 2024
1 parent 99b5e2d commit 47c37b2
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 16 deletions.
6 changes: 6 additions & 0 deletions .changeset/breezy-flies-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@rdfjs-elements/formats-pretty': patch
'@rdfjs-elements/rdf-editor': patch
---

Parsing n3 rules would fail. Using the package [n3](https://npm.im/n3) to support them.
21 changes: 13 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/formats/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from './serializers/graphy.js'
import { TrigParser, NQuadsParser } from './parsers/graphy.js'
import JsonLdSerializer from './serializers/jsonld.js'
import { N3Parser } from './parsers/n3.js'

const formats = new Formats({})
formats.import(formatsCommon)
Expand All @@ -32,7 +33,7 @@ formats.serializers.set(mediaTypes.turtle, new TurtleSerializer())
formats.serializers.set(mediaTypes.trig, new TrigSerializer())
formats.serializers.set(mediaTypes.rdfXml, new RdfXmlSerializer())

formats.parsers.set(mediaTypes.notation3, new TrigParser())
formats.parsers.set(mediaTypes.notation3, new N3Parser())
formats.parsers.set(mediaTypes.turtle, new TrigParser())
formats.parsers.set(mediaTypes.trig, new TrigParser())
formats.parsers.set(mediaTypes.ntriples, new NQuadsParser())
Expand Down
3 changes: 2 additions & 1 deletion packages/formats/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@tpluscode/rdf-ns-builders": ">=3.0.2",
"@zazuko/formats-lazy": "^1.0.1",
"@zazuko/prefixes": "^2.0.0",
"n3": "^1.23.1",
"readable-stream": ">=3.6.0"
},
"devDependencies": {
Expand All @@ -45,7 +46,7 @@
"@types/rdfjs__formats": "^4",
"@types/rdfjs__term-map": "^2",
"@types/rdfjs__term-set": "^2",
"@zazuko/env-node": "^2.1.1",
"@zazuko/env-node": "^2.1.4",
"@zazuko/prefixes": "^2.0.0",
"@zazuko/rdf-utils-fs": "^3.3.1",
"chai": "^4.3.4",
Expand Down
13 changes: 13 additions & 0 deletions packages/formats/parsers/n3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { lazySink } from '@zazuko/formats-lazy/LazySink.js'

export const N3Parser = lazySink(async () => {
const n3 = await import('n3')
return class {
// eslint-disable-next-line class-methods-use-this
import(quadStream, options) {
return new n3.StreamParser({ format: 'text/n3' }).import(quadStream, {
...options,
})
}
}
})
40 changes: 34 additions & 6 deletions packages/formats/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as ns from '@tpluscode/rdf-ns-builders'
import getStream from 'get-stream'
import { join, dirname } from 'path'
import { fileURLToPath } from 'url'
import { Transform } from 'readable-stream'
import formats, { mediaTypes } from '../index.js'

const { parsers, serializers } = formats
Expand Down Expand Up @@ -40,6 +41,25 @@ describe('@rdfjs-elements/formats-pretty', () => {
)
})
})

describe('n3', () => {
it('parses a N3 document with rules', async () => {
// given
const input = `{
?s a ?o .
?o <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?o2 .
} => {
?s a ?o2 .
} .`

// when
const quads = parsers.import(mediaTypes.notation3, toStream(input))
const dataset = await $rdf.dataset().import(quads)

// then
expect(dataset.size).to.eq(4)
})
})
})

describe('serializers', () => {
Expand Down Expand Up @@ -68,20 +88,28 @@ describe('@rdfjs-elements/formats-pretty', () => {
for (const format of Object.values(mediaTypes)) {
it(`graph ${file} in format ${format}`, async () => {
// given
const graph = await $rdf
const data = await $rdf
.dataset()
.import($rdf.fromFile(join(__dirname, `graphs/${file}`)))

// when
const serialized = await getStream(
serializers.import(format, graph.toStream())
serializers.import(format, data.toStream())
)
const roundTrip = await $rdf
.dataset()
.import(parsers.import(format, toStream(serialized)))
const parserStream = parsers
.import(format, toStream(serialized))
.pipe(
new Transform({
objectMode: true,
transform({ subject, predicate, object, graph }, _, callback) {
callback(null, $rdf.quad(subject, predicate, object, graph))
},
})
)
const roundTrip = await $rdf.dataset().import(parserStream)

// then
expect(roundTrip.toCanonical()).to.eq(graph.toCanonical())
expect(roundTrip.toCanonical()).to.eq(data.toCanonical())
})
}
}
Expand Down

0 comments on commit 47c37b2

Please sign in to comment.